Если вы хотите сохранить ваш трубопровод:
f=file.txt
tmp=$(mktemp)
grep " 287 " "$f" | grep "HI" | sed 's/HIS/HID/g' > "$tmp" && mv "$tmp" "$f"
Или, упрощать:
sed -i -n '/ 287/{/HI/ s/HIS/HID/p}' file.txt
Это будет отфильтровывать любую строку, которая не содержит «287» и «HI», - это то, что вы хотите? Я подозреваю, что вы действительно хотите:
sed -i '/ 287/{/HI/ s/HIS/HID/}' file.txt
Для линий, которые соответствуют / 287 /
, выполнять команды в фигурных скобках. Там, для линий, которые соответствуют /HI/
, найдите первый «HIS» и замените на «HID». sed неявно печатает все строки, если -n
не указан.
Других команд, которые делают то же самое:
awk '/ 287/&& /HI/ {sub(/HIS/, "HID")} {print}' file.txt > new.txt
perl -i -pe '/ 287/and /HI/ and s/HIS/HID/' file.txt
AWK не имеет опции «на месте» (за исключением gawk -i inplace
для последних версий поглазеть)
'-i' является для«инверсии редактирование места "вы не можете« редактировать на месте »поток, поэтому' sed' ожидает файл, но вы его не получили. –
yep, но если я удалю - я его не напишу в файл ... – nicetry
Ни одна из этих команд не записывает в файл. Если вы хотите, чтобы выход из 'sed' отправился в файл, вам нужно перенаправить его в файл. '-i' вам не поможет. И вы не можете просто вставить '> file.txt' в конец, так как это будет сначала усекать. Это означает, что 'sed' может сделать для вас всю фильтрацию, поэтому вам совсем не нужно' grep'. –