sedgrep

grep + grep + sed = sed: no input files


Can anybody help me please?

grep " 287 " file.txt | grep "HI" | sed -i 's/HIS/HID/g' 

sed: no input files

Tried also xargs

grep " 287 " file.txt | grep HI | xargs sed -i 's/HIS/HID/g'
sed: invalid option -- '6'

This works fine

grep " 287 " file.txt | grep HI

Solution

  • If you want to keep your pipeline:

    f=file.txt
    tmp=$(mktemp)
    grep " 287 " "$f" | grep "HI" | sed 's/HIS/HID/g' > "$tmp" && mv "$tmp" "$f"
    

    Or, simplify:

    sed -i -n '/ 287 / {/HI/ s/HIS/HID/p}' file.txt
    

    That will filter out any line that does not contain " 287 " and "HI" -- is that what you want? I suspect you really want this:

    sed -i '/ 287 / {/HI/ s/HIS/HID/}' file.txt
    

    For lines that match / 287 /, execute the commands in braces. In there, for lines that match /HI/, search for the first "HIS" and replace with "HID". sed implicitly prints all lines if -n is not specified.

    Other commands that do the same thing:

    awk '/ 287 / && /HI/ {sub(/HIS/, "HID")} {print}' file.txt > new.txt
    perl -i -pe '/ 287 / and /HI/ and s/HIS/HID/' file.txt
    

    awk does not have an "in-place" option (except gawk -i inplace for recent gawk versions)