Linux的sys文件系统表示一组CPU ID,语法为:
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
?
答案 0 :(得分:0)
尝试:
$ 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
,我们按原样打印出来。 vw
是awk的简写版本。
答案 1 :(得分:0)
Perl one:
echo "0,2,4-6,8" | perl -lpe 's/(\d+)-(\d+)/{$1..$2}/g; $_="echo {$_}"' | bash
只需将原始字符串转换为echo {0,2,{4..6},8}
,然后让bash&#39;支持扩展&#39;插入它。
答案 2 :(得分:-1)
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循环。