XYZNA0000778800Z
16123000012300321000000008000000000000000
16124000012300322000000007000000000000000
17234000012300323000000005000000000000000
17345000012300324000000004000000000000000
17456000012300325000000003000000000000000
9
XYZNA0000778900Z
16123000012300321000000008000000000000000
16124000012300322000000007000000000000000
17234000012300323000000005000000000000000
17345000012300324000000004000000000000000
17456000012300325000000003000000000000000
9
我有以上文件格式,我想从中找到匹配的记录。例如,匹配从XYZ开始在线的数字(7789),并且一旦匹配,在下面的行中查找匹配的数字(7345),从1开始,直到它到达从9开始的行。检索整个行记录。如何使用shell脚本,awk,sed或任何组合来完成此任务。
预期产出:
XYZNA0000778900Z
17345000012300324000000004000000000000000
答案 0 :(得分:1)
用sed可以做到:
$ sed -n '/^XYZ.*7789/,/^9$/{/^1.*7345/p}' file
17345000012300324000000004000000000000000
故障:
sed -n ' ' # -n disabled automatic printing
/^XYZ.*7789/, # Match line starting with XYZ, and
# containing 7789
/^1.*7345/p # Print line starting with 1 and
# containing 7345, which is coming
# after the previous match
/^9$/ { } # Match line that is 9
range { stuff }
会在stuff
内执行range
,在这种情况下,范围从/^XYZ.*7789/
开始,以/^9$/
结尾。
.*
将匹配除换行符之外的任何内容。
答案 1 :(得分:0)
我使用awk:
awk -v rid=7789 -v fid=7345 -v RS='\n9\n' -F '\n' 'index($1, rid) { for(i = 2; i < $NF; ++i) { if(index($i, fid)) { print $i; next } } }' filename
其工作原理如下:
-v RS='\n9\n'
是整个事情的核心。 Awk将其输入分成记录(默认行)。这会将记录分隔符设置为\n9\n
,这意味着记录由行分隔,并且单个9
。这些记录进一步分为字段和-F '\n'
告诉awk记录中的字段由换行符分隔,以便记录中的每一行都成为一个字段。-v rid=7789 -v fid=7345
将两个awk变量rid
和fid
(分别称为记录标识符和字段标识符。名称是任意的。)设置为搜索字符串。您可以直接在awk脚本中对这些进行编码,但这样可以更容易,更安全地将值替换为shell变量(我希望您可以这样做)。然后是代码:
index($1, rid) { # In records whose first field contains rid
for(i = 2; i < $NF; ++i) { # Walk through the fields from the second
if(index($i, fid)) { # When you find one that contains fid
print $i # Print it,
next # and continue with the next record.
} # Remove the "next" line if you want all matching
} # fields.
}
请注意,POSIX awk并不严格要求使用多字符记录分隔符,并且我不确定BSD awk是否接受它。不过,GNU awk和mawk都可以。
编辑:第一次误读问题。
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -n '/^XYZ/h;//!H;/^9/!b;x;/^XYZ[^\n]*7789/!b;/7345/p' file
使用选项-n
表示sed的grep-like性质。收集以XYZ
开头并以9
结尾的记录。拒绝标题中没有7789
的所有记录。打印包含7345
的所有剩余记录。
如果7345
始终跟随标题,则可以缩短为:
sed -n '/^XYZ/h;//!H;/^9/!b;x;/^XYZ[^\n]*7789.*7345/p' file
如果所有记录格式正确(开始XYZ
并以9
结尾),请使用:
sed -n '/^XYZ/h;//!H;/^9/!b;x;/^[^\n]*7789.*7345/p' file