我是shell脚本的新手,必须围绕它编写很多任务。我试图尽可能快地学习,但有时候shell脚本使得任务看起来很容易,而在其他时候它只是玩具和我一起玩。我现在面临着类似的情况。 我有一个命令,它给我一个像这样的输出。
File Dependents
----------------------------------------------------------------------------
<File> is a requisite of <Dependents>
Path: /usr/lib/obj
Java 1.0.0.0 analysis 0.0.0.2
runtime 1.2.0.0
client 1.2.0.0
framework 6.1.9.100
sguide 1.9.10.0
sysmgt 6.1.9.100
dsm 6.1.9.200
Path: /etc/obj
Java 1.0.0.0 analysis 1.2.0.2
runtime 2.0.0.0
client3 6.1.9.0
sysmgt 6.1.9.0
dsm2 6.1.9.0
现在我想将依赖项列表放入一个数组中以便进一步处理。这是我到目前为止能够做到的:
<command> | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}'
输出是:
Java<<< I want this to be analysis
runtime
client
framework
sguide
sysmgt
dsm
Java<<< want this to be analysis
runtime
client3
sysmgt
dsm2
我必须在两个单独的数组中捕获这两个列表。
有人可以帮助我以优雅的方式实现此输出。我不想用我的暴力方法来处理这些代码,包括很多条件和比较。
答案 0 :(得分:2)
awk
救援!
$ arr1=$(command ... | awk -v c=1 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}')
$ arr2=$(command ... | awk -v c=2 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}')
$ echo $arr1
analysis runtime client framework sguide sysmgt dsm
$ echo $arr2
analysis runtime client3 sysmgt dsm2
如果运行一次命令并将结果拆分为两个数组,可能会更好。
<强>解释强>
awk -v c=1
将awk变量c设置为1(描述组实例编号)
'!NF{f=0}
如果没有字段(空行)重置f
f && s==c{print $1}
如果设置了f并且计数器等于c则打印第一个字段
/Java/{f=1; s++;
当模式与Java匹配时,设置f并增加计数器和...if(s==c) print $(NF-1)}'
如果计数器匹配c打印倒数第二个字段。
答案 1 :(得分:1)
您可以先使用Java删除子字符串来修复解决方案:
command | sed 's/Java [^ ]*//' | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}'
使用awk
时,您可以更好地使用awk
的全部力量。只是说你希望打印带有数字的任何一行的倒数第二个字段:
command | awk '/[0-9]/ { print $(NF-1) }'
这比尝试使用sed
更好(你有标签或空格吗?)
command | sed -n '/[0-9].[0-9]/ s/^.* \([^ ]*\) .*/\1/p'
一个有趣的解决方案是使用rev
来还原您的文字。那样cut
可以找到第二个字段。
command | grep '[0-9].[0-9]' | rev | cut -d " " -f2 | rev
对于只阅读最后一行的人,我将重复awk
解决方案:
command | awk '/[0-9]/ { print $(NF-1) }'