Jua*_*.A. 5 grep text-processing
是否可以使用grep一个文件运行的多行输出作为模式,以便与另一个文件的后续第二次grep运行一起使用?
例子:
file1.txt
2 blue
1 red
1 green
2 black
2 orange
Run Code Online (Sandbox Code Playgroud)
file2.txt
2 blue triangle
2 blue circle
3 blue triangle
2 red triangle
3 green circle
4 red square
2 orange circle
2 brown circle
Run Code Online (Sandbox Code Playgroud)
grep:
2 blue
1 red
1 green
2 black
2 orange
Run Code Online (Sandbox Code Playgroud)
现在,我正在寻找一个可以实现类似功能的命令
2 blue triangle
2 blue circle
3 blue triangle
2 red triangle
3 green circle
4 red square
2 orange circle
2 brown circle
Run Code Online (Sandbox Code Playgroud)
这将找到其中的所有行均以运行 onfile2.txt生成的行之一开头,因此所需的结果是:grepfile1.txt
2 blue triangle
2 blue circle
2 orange circle
Run Code Online (Sandbox Code Playgroud)
Adm*_*Bee 15
这是字面问题的答案。要获得可能更好地解决该任务的答案,请参阅awk下面“注释”中的解决方案。
假设在 中找到的模式file1.txt只能出现在 中 行的开头file2.txt,您可以使用该-f标志从文件中读取多个搜索模式,而不是在命令行上将它们声明为正则表达式。然后需要将该文件连接到第一次grep运行的输出。
一种方法是进程替换:
\ngrep -F -w -f <(grep -w 2 file1.txt) file2.txt\nRun Code Online (Sandbox Code Playgroud)\n<( ... )构造使得括号中的命令的输出可用,就像它是一个文件一样。-F标志禁用完整的正则表达式搜索,是为了安全起见,以防第一次grep运行的输出可能包含在正则表达式上下文中具有特殊含义的字符。它还加快了匹配速度,因为文字字符串比较比正则表达式匹配更快。-w标志确保不会有部分匹配进入结果。grep如果 的第一列file1.txt可以包含多位数字,例如 ,这对于第一次运行尤其可取12。更新
\n正如 @St\xc3\xa9phane Chazelas 所指出的,该-f选项接受经常(但并非总是)实现的值-来引用程序的stdin,因此您也可以将其写为
grep -w 2 file1.txt | grep -F -w -f - file2.txt\nRun Code Online (Sandbox Code Playgroud)\n使用更容易识别的管道方法来读取另一个命令的输出。
\n笔记
\n这假设该模式number color只能作为 的前两列出现file2.txt。如果它也可以稍后发生在线路上,如
4 red square and 2 blue triangle\nRun Code Online (Sandbox Code Playgroud)\n这样的行会被错误地识别为也匹配。
\n对于处理表格数据(似乎是这里的情况),awk通常是更适合的工具。您的任务可以通过以下程序来完成awk:
4 red square and 2 blue triangle\nRun Code Online (Sandbox Code Playgroud)\n这将处理这两个文件。awk搜索关键字通过变量指定num。
在处理第一个文件时(其中NR,全局行计数器,等于FNR,每个文件行计数器),它会在数组索引的 col第二列中注册颜色(因此没有实际分配给col[$2]),如果第一列匹配。然后它会跳到下一行执行。
处理第二个文件时,它检查第一列是否与num变量匹配,以及是否在数组的索引中找到第二列col。如果是这样,则打印该行。
解决了:
$ grep 2 file1.txt | xargs -I{} grep {} file2.txt
2 blue triangle
2 blue circle
2 orange circle
Run Code Online (Sandbox Code Playgroud)