2015-03-26 2 views
1

Может кто-нибудь мне помочь?grep + grep + sed = sed: нет входных файлов

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

sed: no input files 

Пробовал также xargs

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

Это прекрасно работает

grep " 287 " file.txt | grep HI 
+2

'-i' является для«инверсии редактирование места "вы не можете« редактировать на месте »поток, поэтому' sed' ожидает файл, но вы его не получили. –

+0

yep, но если я удалю - я его не напишу в файл ... – nicetry

+0

Ни одна из этих команд не записывает в файл. Если вы хотите, чтобы выход из 'sed' отправился в файл, вам нужно перенаправить его в файл. '-i' вам не поможет. И вы не можете просто вставить '> file.txt' в конец, так как это будет сначала усекать. Это означает, что 'sed' может сделать для вас всю фильтрацию, поэтому вам совсем не нужно' grep'. –

ответ

2

Если вы хотите сохранить ваш трубопровод:

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 для последних версий поглазеть)

+0

Да, последний работает отлично, можете ли вы это немного объяснить? – nicetry

+0

Как я могу изменить файл.txt за $ 1. $ 1 - пользовательский ввод при работе sh. – nicetry

+0

Как вы думаете, что бы вы сделали? –

Смежные вопросы