使用awk,sed,grep解析具有特定标题的文件部分

时间:2016-01-25 19:43:20

标签: awk sed grep

我有一个文件,我分解成一堆不同的标题。我需要特定标题下的某些字段。例如,我想在PRIORITY USERS标题下打印名称。我可以使用grep grep这个段并打印名称(如grep -A 10" PRIORITY USERS" | grep name :)但我需要将输出限制为PRIORITY USERS标题下的名称。问题是每个标题下的条目数有所不同,所以我不能使用带有grep -A选项的固定数字

你能帮忙吗?

输入文件

USERS:

           name: 286
           fields1
           fields 3 

           name: 123
           fieldx: test


PRIORITY USERS:

           name: jack
           field1:  8
           name: Joe


           name: bob
           field1: xyz

           name: tempo
           kind: Text


 SEGMENT3 

           name: ginger
           name: max

 Non-USERS

           Name: JOJO 

输出应为:

PRIORITY USERS:  

    name: jack 
    name: bob
    name: tempo 

提前感谢你们

5 个答案:

答案 0 :(得分:1)

awk -vRS= -F'\n' '/SEGMENT/{a=0}a{$0=$1}/PRIORITY/{a=1}a' file
PRIORITY USERS:
           name: jack
           name: bob
           name: tempo

答案 1 :(得分:1)

$ cat tst.awk
/^[[:space:]]?[^[:space:]]/ { inSect = ($0 ~ ("^[[:space:]]?" sect "[[:space:]:]*$") ? 1 : 0) }
inSect && ($0 ~ "^[[:space:]]+" field ":")

$ awk -v sect='PRIORITY USERS' -v field='name' -f tst.awk file
           name: jack
           name: Joe
           name: bob
           name: tempo

上面的内容很复杂,因为你的输入格式非常变化,有些标题行以空格开头,其他没有,有些有直接的尾随分号,有些则有空格等等。它假设你错过了{{ 1}}来自您的预期输出。

答案 2 :(得分:0)

cat sample.csv

USERS:

           name: 286
           fields1
           fields 3

           name: 286
           fields 4

PRIORITY USERS:

           name: Jack
           field1:  8
           name: Joe

 SEGMENT3

           name: ginger
           name: max

 Non-USERS

           Name: JOJO

sed -n'/ PRIORITY USERS /,/ SEGMENT3 / p'sample.csv | grep名称

   name: Jack
   name: Joe

'/ PRIORITY USERS /,/ SEGMENT3 /'优先使用者是开始模式,SEGMENT3是结束模式,我们只打印出这两种模式之间的界限,然后获得name

答案 3 :(得分:0)

看起来顶级标题可以表征为最多以一个空白开头的行。如果是这种情况,那么以下优点是不需要了解目标标题之后的顶级标题:

sed -r -n '/^ ?PRIORITY USERS/,/^ ?[^ ]/ {/name:/p ; }'

(某些版本的sed需要-E而不是-r以支持扩展正则表达式。)

在任何情况下,都无需同时调用sedgrep

使用&aw;'这是你可以使用"?"在正则表达式中,无需设置标志:

awk '/^ ?PRIORITY USERS/ {s++; next}
     s==1 {if (/^ ?[^ ]/) {s++} else if (/name:/) {print}}'

答案 4 :(得分:0)

awk救援!

$ awk -v RS= 'f{print;exit} /PRIORITY USERS:/{f=1}' file

           name: ack
           field1:  8
           name: Joe

我想,也有一个不成文的要求来过滤非名字行。为此,稍微更改脚本

$ awk -F'\n' -v RS= 'f{for(i=1;i<=NF;i++) if($i~/name:/) print $i;exit}
     /PRIORITY USERS:/{f=1}' file

           name: ack
           name: Joe

更新:根据更新的输入文件,这将生成名单

$ awk '/SEGMENT3/{f=0} f&&/name:/; /PRIORITY USERS:/{f=1}' file

           name: jack
           name: Joe
           name: bob
           name: tempo

注意:您的输出样本丢失了&#34; Joe&#34;。如果你错过了&#34; bob&#34;,那就是一个不错的笑话!