使用多个图案显示多行

时间:2015-01-07 22:19:17

标签: grep

希望你能解释我的一个要求。假设我有以下条目的文件:

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

2 个答案:

答案 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打印,没有尾随换行符,两个连接的东西:
    • 如果我们在ABC线上,换行符(\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