多个 grep 的替代方案

多个 grep 的替代方案

我正在读取 shell 脚本中的 pipeline 输出列表并查找特定条目。我不知道确切的名字,但我知道里面的单词。为了找到它,我对我知道将出现在条目中的每个单词使用多个 grep

pw-cli list-objects | grep node.name | grep output | grep pci | grep analog

这样做还有其他选择吗?谢谢。

答案1

我会为此使用 awk:

pw-cli list-objects | awk '/node\.name/ && /output/ && /pci/ && /analog/'

或者如果我需要 perl 的正则表达式语法或其他 perl 语言功能或库模块(本示例实际上都不需要),则可能是 perl:

pw-cli list-objects | 
  perl -n -e 'print if (/node\.name/ && /output/ && /pci/ && /analog/)'

为此使用 awk 或 perl 有两个主要好处:

  1. 无论输入中单词的顺序如何,它都会匹配输入行。即node\.name.*output.*pci.*analog,仅当这些单词位于输入行中时,类似的正则表达式才会匹配确切地那个订单。如果所有四个单词以任何顺序出现在输入行中的任何位置,则上面的 awk 或 perl 单行语句将匹配 - 这相当于您grep在管道中将多个 s 链接在一起的方式。

    可以对于每个位置变化,使用带有替换 ( ) 的扩展正则表达式|,但是对于四个单词,您需要 16 个替换版本来匹配每种可能的排列,所以这是不切实际的 -(a.*b.*c.*d)|(a.*c.*b.*d)|(a.*b.*d.*c)|.........

  2. &&您可以使用(AND)、||(OR)、 (否定) 和括号的任意组合!来构造任意复杂的布尔条件。您还可以与任何其他返回 true 或 false 结果的 awk 或 perl 语法结合使用(例如,基于输入行中的字段进行计算和比较)。

答案2

是的,通过使用“正则表达式”。读man grep

# if they're on the same linr
pw-cli | grep 'node\.name.*output.*pci.*analog'
# or if they're not
pw-cli | grep 'node\.name|output<pci|analog'

相关内容