Linux的sys文件系统用语法表示一组CPU ids:
0,2,8
:一组包含0、2和8的CPU。4-6
:一组包含4、5和6的CPU。0,2,4-6,8
例如,在我的机器上运行cat /sys/devices/system/cpu/online
打印0-3
,这意味着CPU 0、1、2和3在线。
问题是上面的语法很难在shell脚本中使用for循环来迭代。如何将上述语法转换为更常规的语法,如0 2 4 5 6 8
发布于 2018-05-19 22:49:48
尝试:
$ echo 0,2,4-6,8 | awk '/-/{for (i=$1; i<=$2; i++)printf "%s%s",i,ORS;next} 1' ORS=' ' RS=, FS=-
0 2 4 5 6 8
这可以在循环中使用,如下所示:
for n in $(echo 0,2,4-6,8 | awk '/-/{for (i=$1; i<=$2; i++)printf "%s%s",i,ORS;next} 1' RS=, FS=-)
do
echo cpu="$n"
done
它产生的输出:
cpu=0
cpu=2
cpu=4
cpu=5
cpu=6
cpu=8
或者说:
printf "%s" 0,2,4-6,8 | awk '/-/{for (i=$1; i<=$2; i++)printf "%s%s",i,ORS;next} 1' RS=, FS=- | while read n
do
echo cpu="$n"
done
它还产生了:
cpu=0
cpu=2
cpu=4
cpu=5
cpu=6
cpu=8
它是如何工作的
awk命令的工作方式如下:
RS=,
这告诉awk使用,
作为记录分隔符。
例如,如果输入是0,2,4-6,8
,那么awk将看到四条记录:0
和2
以及4-6
和8
。FS=-
这告诉awk使用-
作为字段分隔符。
使用FS
这样设置,例如,如果输入记录由2-4
组成,那么awk将将2
视为第一个字段,将4
视为第二个字段。/-/{for (i=$1; i<=$2; i++)printf "%s%s",i,ORS;next}
对于包含-
的任何记录,我们打印每个数字,从第一个字段$1
的值开始,以第二个字段$2
的值结尾。每个这样的数字后面跟着输出记录分隔符ORS
。默认情况下,ORS
是换行符。对于上面的一些示例,我们将ORS
设置为空白。
打印这些数字之后,我们跳过其余的命令并跳转到next
记录。1
如果我们到了这里,那么记录中不包含-
,我们按原样打印出来。1
是awk打印行的缩写.发布于 2018-05-20 00:12:46
一个Perl程序:
echo "0,2,4-6,8" | perl -lpe 's/(\d+)-(\d+)/{$1..$2}/g; $_="echo {$_}"' | bash
只需将原始字符串转换为echo {0,2,{4..6},8}
,并让bash‘大括号展开’插值它。
发布于 2018-05-19 22:26:25
eval echo $(cat /sys/devices/system/cpu/online | sed 's/\([[:digit:]]\+\)-\([[:digit:]]\+\)/$(seq \1 \2)/g' | tr , ' ')
解释:
cat /sys/devices/system/cpu/online
从sysfs读取文件。这可以更改为任何其他文件,如offline
。s/\([[:digit:]]\+\)-\([[:digit:]]\+\)/$(seq \1 \2)/g
进行管道传输。这将匹配类似于4-6
的内容,并将其替换为$(seq 4 6)
。tr , ' '
用空格替换所有逗号。0,2,4-6,8
被转换为0 2 $(seq 4 6) 8
。最后一步是对这个序列进行eval
以获得0 2 4 5 6 8
。echo
的输出。或者,它可以写入变量或在for循环中使用。https://stackoverflow.com/questions/50430036
复制相似问题