Search code examples
loopssedgrep

use sed group variable within loop for another grep


Context: grep on result of sed grouping, within a loop

grep "blah" x.txt | sed 's/cheese\(.*\)/xlogs\/butter\1.log/g' | while read -r line; do
 echo $line; 
 //TODO: grep -r "$1" another_file.txt
done

above code works, to replace cheese123 with xlogs/butter123.log, retaining 123 variable, over the result of blah search. All good.

I want to use the captured 123 in the grouping, for another grep in another file, in the loop. Say even echo $1 aka 123 would suffice.

How do I do that, thanks in advance.


Solution

  • One option is to output two lines:

    grep "blah" x.txt |
    sed -n 's/cheese\(.*\)/xlogs\/butter\1.log\n\1/p' |
    while IFS= read -r line1 && IFS= read -r line2; do
       echo "$line1"
       # TODO: grep "$line2" another_file.txt
    done
    

    To avoid the output getting out of sync if the sed command doesn't make any substitution, -n and s///p are used so that no output is produced in that case.

    s///g flag is not needed since there can be only one match on a line.

    The first grep could also be part of the sed:

    sed -n '/blah/s/cheese\(.*\)/xlogs\/butter\1.log\n\1/p' x.txt |
    while ...
    

    @edmorton reminded me that using \n in replacement text is non-standard and not accepted by all implementations of sed (it may just turn into n). A newline can be inserted literally if preceded by a backslash (ensure there is no trailing whitespace):

    | sed -n 's/cheese\(.*\)/xlogs\/butter\1.log\
    \1/p' |
    

    or in a more convoluted way like:

    | sed -n 'G; s/cheese\(.*\)\(.\)/xlogs\/butter\1.log\2\1/p' |