grep 输出前一个 grep

Jua*_*.A. 5 grep text-processing

是否可以使用grep一个文件运行的多行输出作为模式,以便与另一个文件的后续第二次grep运行一起使用?

例子:

现在,我正在寻找一个可以实现类似功能的命令

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下面“注释”中的解决方案。

\n

假设在 中找到的模式file1.txt只能出现在 中 行的开头file2.txt,您可以使用该-f标志从文件中读取多个搜索模式,而不是在命令行上将它们声明为正则表达式。然后需要将该文件连接到第一次grep运行的输出。

\n

一种方法是进程替换

\n
grep -F -w -f <(grep -w 2 file1.txt) file2.txt\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • <( ... )构造使得括号中的命令的输出可用,就像它是一个文件一样。
  • \n
  • -F标志禁用完整的正则表达式搜索,是为了安全起见,以防第一次grep运行的输出可能包含在正则表达式上下文中具有特殊含义的字符。它还加快了匹配速度,因为文字字符串比较比正则表达式匹配更快。
  • \n
  • -w标志确保不会有部分匹配进入结果。grep如果 的第一列file1.txt可以包含多位数字,例如 ,这对于第一次运行尤其可取12
  • \n
\n

更新

\n

正如 @St\xc3\xa9phane Chazelas 所指出的,该-f选项接受经常(但并非总是)实现的值-来引用程序的stdin,因此您也可以将其写为

\n
grep -w 2 file1.txt | grep -F -w -f - file2.txt\n
Run Code Online (Sandbox Code Playgroud)\n

使用更容易识别的管道方法来读取另一个命令的输出。

\n
\n

笔记

\n
    \n
  1. 这假设该模式number color只能作为 的前两列出现file2.txt。如果它也可以稍后发生在线路上,如

    \n
    4 red square and 2 blue triangle\n
    Run Code Online (Sandbox Code Playgroud)\n

    这样的行会被错误地识别为也匹配。

    \n
  2. \n
  3. 对于处理表格数据(似乎是这里的情况),awk通常是更适合的工具。您的任务可以通过以下程序来完成awk

    \n
    4 red square and 2 blue triangle\n
    Run Code Online (Sandbox Code Playgroud)\n

    这将处理这两个文件。awk搜索关键字通过变量指定num

    \n

    在处理第一个文件时(其中NR,全局行计数器,等于FNR,每个文件行计数器),它会在数组索引的 col第二列中注册颜色(因此没有实际分配给col[$2]),如果第一列匹配。然后它会跳到下一行执行。

    \n

    处理第二个文件时,它检查第一列是否与num变量匹配,以及是否在数组的索引中找到第二列col。如果是这样,则打印该行。

    \n
  4. \n
\n


Jua*_*.A. 0

解决了:

$ grep 2 file1.txt | xargs -I{} grep {} file2.txt

2 blue triangle
2 blue circle
2 orange circle
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“xargs”会因引号或反斜杠字符而阻塞,并删除前导空格。`grep` 也会阻塞以 `-` 开头的字符串(您需要 `--` 或 `-e`),并将它们视为正则表达式(您可能需要 `-F`)。所以 `grep 2 file1.txt | xargs -d '\n' -I {} grep -Fe {} file2.txt` (假设 GNU `xargs`),尽管这仍然非常低效,因为它在 `file1 的每个匹配行的 `grep` 上运行。 txt`,每个都完整读取`file2.txt`。 (6认同)