grep -f文件按顺序打印为文件

时间:2014-02-20 13:09:47

标签: linux bash shell grep

我需要从文件中grep模式,但需要按顺序。

$ cat patt.grep
name1
name2

$ grep -f patt.grep myfile.log
name2:some xxxxxxxxxx
name1:some xxxxxxxxxx

我正在获取输出,因为name2首先被打印,然后发现name1也被打印出来。但我的要求是按照patt.grep文件的顺序首先获取name1。

我期待输出为

name1:some xxxxxxxxxx
name2:some xxxxxxxxxx

6 个答案:

答案 0 :(得分:4)

您可以将patt.grep发送到xargs,这样可以一次将模式传递给grep

默认情况下xargs在命令末尾附加参数。但在这种情况下,grep需要myfile.log才能成为最后一个参数。因此,请使用-I{}选项告诉xargs{}替换为参数。

cat patt.grep | xargs -Ihello grep hello myfile.log

答案 1 :(得分:2)

我尝试了相同的情况,并使用以下命令轻松解决:

我认为如果您的数据格式与您所代表的格式相同,则可以使用此格式。

grep -f patt.grep myfile.log | sort

enter image description here

答案 2 :(得分:0)

通过逐行阅读,按照出现的顺序逐个使用patt.grep中的正则表达式:

while read ptn; do grep $ptn myfile.log; done < patt.grep

答案 3 :(得分:0)

一个简单的解决方法是sort之前grep日志文件:

grep -f patt.grep <(sort -t: myfile.log)

但是,如果patt.grep未排序,则可能无法以所需顺序生成结果。

为了保留模式文件中指定的顺序,您可以改为使用awk

awk -F: 'NR==FNR{a[$0];next}$1 in a' patt.grep myfile.log

答案 4 :(得分:0)

仅在grep中无法完成此操作。

对于一个简单实用但效率低下的解决方案,请参阅owlman's answer。它会为grep中的每个模式调用一次patt.grep

如果这不是一个选项,请考虑以下方法:

grep -f patt.grep myfile.log |
 awk -F: 'NR==FNR { l[$1]=$0; next } $1 in l {print l[$1]}' - patt.grep
  • 一次性将所有模式传递给grep
  • 然后使用patt.grep根据awk中的模式顺序对它们进行排序:
    • 首先读取所有输出行(通过stdin,-,即通过管道传递)到一个assoc。使用基于:的第一个字段作为键
    • 的数组
    • 然后遍历patt.grep的行并打印相应的输出行(如果有的话)。

约束

  • 假设patt.grep中的所有模式都与日志文件中基于:的第一个标记相匹配,正如问题中的示例输出数据所暗示的那样。
  • 假设每个模式只匹配一次 - 如果可能有多个匹配,则必须使awk解决方案更加复杂。

答案 5 :(得分:0)

这应该这样做

awk -F“:”'NR == FNR {a [$ 1] = $ 0; next} {if($ 1 in a){print a [$ 0]} else {print $ 1,$ 1}}'myfile.log patt.grep&gt; ž