希望你能解释我的一个要求。假设我有以下条目的文件:
ABC 123 XYZ 789 XYZ 456 ABC 234 XYZ 789 ABC 567 XYZ 789 XYZ 678 XYZ 123
基本上,我有行ABC,其后面有X个XYZ行。每个ABC中XYZ记录的数量从1到多不等。
我需要一个shell脚本,它将根据第二列中的模式输出ABC和相应的XYZ。
例如,显示带有模式567的ABC记录和带有模式678的相应XYZ记录。
输出应该只是:
ABC 567 XYZ 678
答案 0 :(得分:0)
尝试这个,如果它适合你。我希望我理解你的要求:
awk -v p1='ABC 567' -v p2='XYZ 678'
'$0~p1{t=1;print;next}/^ABC/{t=0}$0~p2&&t' file
答案 1 :(得分:0)
要解决此问题,我使用awk
将数据按到一行,然后在该输出上按grep
,然后sed
将匹配的条目恢复为原始格式。
awk '{ printf ($1 == "ABC" ? "\n" : " @¶@ ") $0 }' file |grep 567 |sed 's/ @¶@ /\n/g'
代码漫步:
@¶@
作为分隔符。使用在您的数据中不会发生冲突的内容(否则您将不得不处理它的转义)。另请注意,您的UTF8支持里程可能会有所不同。awk
打印,没有尾随换行符,两个连接的东西:
\n
)。否则,分隔符(@¶@
)。$0
)grep
运行您的查询。这使您可以使用-f FILE_OF_PATTERNS
或-e PATTERN
s sed
然后将分隔符恢复为原始格式这有利于逐行进行。如果你在一个ABC中有成千上万的XYZ,它会慢一点,但这并不能保留在内存中,所以这应该是相当可扩展的。
以上是awk
命令的输出(是的,有一个前导空白行,这并不重要):
$ awk '{ printf ($1 == "ABC" ? "\n" : " @¶@ ") $0 }' file
ABC 123 @¶@ XYZ 789 @¶@ XYZ 456
ABC 234 @¶@ XYZ 789
ABC 567 @¶@ XYZ 789 @¶@ XYZ 678 @¶@ XYZ 123