请注意,该tr -s ' '
选项不会删除任何单个前导空格。如果您的列右对齐(与ps
pid一样)...
$ ps h -o pid,user -C ssh,sshd | tr -s " "
1543 root
19645 root
19731 root
如果是第一列,则切割将导致其中某些字段的空白行:
$ <previous command> | cut -d ' ' -f1
19645
19731
除非您在其前面加上空格,否则显然
$ <command> | sed -e "s/.*/ &/" | tr -s " "
现在,对于pid数字(不是名称)的这种特殊情况,有一个称为的函数pgrep
:
$ pgrep ssh
外壳功能
但是,通常,实际上仍然可以以简洁的方式使用shell函数,因为该read
命令有一个巧妙的地方:
$ <command> | while read a b; do echo $a; done
要读取的第一个参数a
选择第一列,如果还有更多列,则将其他所有内容都放入b
。结果,您所需要的变量永远不会超过+1列的数量。
所以,
while read a b c d; do echo $c; done
然后将输出第三列。如我的评论所示...
管道读取将在不将变量传递给调用脚本的环境中执行。
out=$(ps whatever | { read a b c d; echo $c; })
arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}
阵列解决方案
因此,我们最后得到了@frayser的答案,这是使用默认为空格的shell变量IFS将字符串拆分为数组。它仅在Bash中有效。Dash和Ash不支持它。我在将字符串拆分成Busybox组件中的过程中确实遇到了困难。获得单个组件(例如使用awk),然后针对所需的每个参数重复该过程非常容易。但是随后您最终会在同一行上重复调用awk,或者在同一行上重复使用带有echo的读取块。这不是有效的还是漂亮的。所以你最终使用分裂 ${name%% *}
等等。使您渴望一些Python技能,因为如果您习惯的一半或更多功能消失了,那么实际上,shell脚本就不再有趣了。但是您可以假设即使在这样的系统上也不会安装python,但不是;-)。