0

I am reading a list of outputs for pipewire in a shell script and looking for a specific entry. I don't know the exact name but I know the words that are in it. To find it I am using multiple greps for each word I know will be in the entry

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

Is there an alternative to doing this? Thank you.

muru
  • 69,900
  • 13
  • 192
  • 292
  • 1
    Please [edit] your question to show what the sample input would be and your expected output. As written your code looks for lines that contain **all** of those strings in the same line. – Jim L. Jun 06 '23 at 21:44

2 Answers2

1

I'd use awk for this:

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

Or maybe perl if I needed perl's regex syntax, or other perl language features or library modules (neither of which are actually needed for this example):

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

There are two main benefits in using awk or perl for this:

  1. it will match input lines regardless of the order of words in the input. i.e. a regex like node\.name.*output.*pci.*analog will match only if those words are in the input line in exactly that order. The awk or perl one-liners above will match if ALL four words are present anywhere in the input line, in any order - this is equivalent to the way you've chained multiple greps together in the pipeline.

    You could use extended regexps with alternations (|) for every placement variation, but with four words, you'd need 16 alternate versions to match every possible arrangement, so that's kind of impractical - (a.*b.*c.*d)|(a.*c.*b.*d)|(a.*b.*d.*c)|.........

  2. You can use any combination of && (AND), || (OR), ! (negation), and parentheses to construct an arbitrarily complex boolean conditional. You can also combine with any other awk or perl syntax that returns a true or false result (e.g. calculations & comparisons based on fields within the input line).

cas
  • 1
  • 7
  • 119
  • 185
0

Yes, by using "regular expressions". Read 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'
waltinator
  • 4,439
  • 1
  • 16
  • 21