grep plik i potokuj wyjście do sed i przechowuj wyjście sed w pliku


3

Zawartość source.txt:

gold  green white black blue
yellow magenta brown 
tram kilo charlie tango

Cześć wszystkim! Muszę rozwiązać zagadkę.

Próbuję uruchomić mały skrypt, aby grep pliku source.txt, grepwyjście potoku, aby sedzastąpić ciąg i zapisać tę linię w nowym plikupol.txt

grep -l "gold" source.txt | xargs sed  's/green/red/' >  pol.txt

Zamiast mieć jedyną tę linię w pol.txt:

gold  red white black blue

Mam cały sam plik z ciągiem, który zastąpiłem

gold  red white black blue
yellow magenta brown 
tram kilo charlie tango

Kiedy -lusuwam opcję z polecenia grep, mam to i oczywiście nic w pol.txt

sed: can't read gold: No such file or directory
sed: can't read green: No such file or directory
sed: can't read white: No such file or directory
sed: can't read black: No such file or directory
sed: can't read blue: No such file or directory

grep jest potrzebny jako tester i niestety opcja „jeśli” nie jest opcją.


Na jakim systemie operacyjnym jesteś? I z czym został source.txtzapisany plik? Wydaje mi się, że może to być pomieszanie między zwrotami karetki a pomieszaniem kanałów i linii.
— JakeGould

Jak pokazuje odpowiedź John1234, prawie nigdy nie trzeba używać razem grepi sedrazem - sedsama prawdopodobnie prawdopodobnie może zrobić wszystko, co oba programy mogą zrobić razem. Jeśli masz problem z wieloma plikami wejściowymi i potrzebujesz przetworzyć tylko te, które zawierają „złoto”, prawdopodobnie powinieneś to wyjaśnić; w przeciwnym razie ludzie, którzy próbują odpowiedzieć na twoje pytanie, mają jedną rękę związaną za plecami. (Proszę nie odpowiadać w komentarzach; edytuj swoje pytanie, aby było jaśniejsze i bardziej kompletne.) Jak wyjaśnia Satya Mishra, grep -l "gold" source.txtwyświetli source.txt  … (ciąg dalszy)
— G-Man

(Ciąg dalszy)… jeśli plik zawiera słowo „złoto” (i nic, jeśli nie zawiera). Jeśli jedyną rzeczą, którą zapisujesz w potoku, jest source.txtnazwa pliku, nie ma mowy, aby proces po prawej stronie potoku wiedział, że chcesz, aby przetwarzał tylko linie zawierające „złoto”, chyba że wbudujesz to w polecenie (jak pokazuje John). (Jego komendę można trochę uprościć, aby sed -n '/gold/s/green/red/p' source.txt. A jeśli potrafisz pisać sed 's/green/red/', czy to naprawdę jest tak „przerażające”, że utrzymanie go będzie „bolesne”?)
— G-Man

Odpowiedzi:


4

Aby wybrać dowolną linię zawierającą goldod source.txt i zastąpić pierwsze wystąpienie greenz red:

$ sed  -n '/gold/{s/green/red/; p}' source.txt 
gold  red white black blue

Aby zapisać to w pliku:

sed  -n '/gold/{s/green/red/; p}' source.txt  >pol.txt

Jak to działa

  • -n mówi sed, aby nie drukował linii, chyba że wyraźnie o to poprosimy.

  • /gold/wybiera linie pasujące do wyrażenia regularnego gold.

  • s/green/red/ wykonuje podstawienie

  • p odbitki.

Korzystanie z awk

Z tą samą logiką:

$ awk '/gold/{gsub(/green/, "red"); print}' source.txt 
gold  red white black blue

Korzystanie z grep

Jeśli z powodów jeszcze nie wyjaśnionych jesteśmy zmuszeni do korzystania z potoku grep, spróbuj:

$ grep -l --null "gold" source.txt | xargs -0 sed  -n '/gold/s/green/red/p'
gold  red white black blue

dzięki John za twój wkład, ale grep jest potrzebny. Grep będzie używany jako tester przed przekazaniem wyjścia do sed.
— Driven

1
@Driven Dlaczego uważasz, że grep jest potrzebny jako tester? sed jest w stanie wykonać ten sam test. Chyba że masz jakieś inne wymagania, które nie zostały jeszcze wyjaśnione?
— John1024,

Planuję zautomatyzować ten proces za pomocą pętli for przez kilka plików.
— Driven

Aby przetworzyć kilka plików, nie ma potrzeby używania forpętli. Sed może przyjmować wiele nazw plików w jednym wierszu poleceń. (Jeśli wciąż jest więcej wymagań, zamiast ujawniać swój cel fragmentarycznie, równie dobrze możesz po prostu określić je wszystkie naraz.)
— John1024

@Driven Dodałem wersję z potokiem grep.
— John1024,

1

grep -l "gold" source.txtwyświetli, source.txtjeśli plik zawiera słowo gold xargs sed 's/green/red/', sed 's/green/red/' source.txta końcowe przekierowanie zapisze wynik w twoich wynikach.

Jeśli dobrze rozumiem twoją intencję, potrzebujesz następującego polecenia:

sed -n '/gold/s/green/red/p' source.txt > pol.txt

Te /gold/linie zaznaczane są dopasowane goldi skomenda robi wymiany chcesz.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.