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
复制相似问题