如何在shell脚本中使用awk处理字符串

rmbxnbpk  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(159)

我对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

我必须在两个单独的数组中捕获这两个列表。
有人能帮助我实现这个输出在一个优雅的方式。我不想屠夫这个代码与我的蛮力方法涉及大量的条件和比较。

6psbrbz9

6psbrbz91#

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打印倒数第二个字段。

ttvkxqim

ttvkxqim2#

您可以先用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) }'

相关问题