Podstawienie pierwszego wystąpienia wzorca w linii dla wszystkich linii w pliku za pomocą sed

16

Czy można to zrobić w jednej wkładce?

Mam takie wyjście:

"First line" - Description  
" Second line" - Description  
"Third line" - Description  
" Fourth line" - Description  

To wejście jest generowane automatycznie.

Chcę zamienić pierwsze wystąpienie "(cudzysłów + spacja) na "(cudzysłów) dla każdego wiersza. Gdybym zastosować podstawienie globalnie, będzie to również zmienić każde wystąpienie line" -do line"-, więc zastanawiałem się, czy możliwe jest, aby użyć sed jedną wkładkę do osiągnięcia tego celu.

Próbowałem używać w ^ten sposób

sed -r ':a;N;$!ba;s/(\^\" )/\"/g'

Ale to nie działa, niczego nie zastępuje. próbowałem

sed -r ':a;N;$!ba;s/(^|\" )/\"/g'

i zastępuje wszystkie wystąpienia. Właśnie zacząłem używać sed, więc tak naprawdę nie wiem, czy robię coś źle.

Czego tu brakuje?

Steve B.
źródło
Uwaga na temat etykiet: Polecenie, które napisałeś powyżej, może działać w niektórych implementacjach sed, ale dla przenośności i aby uniknąć naprawdę dziwnych błędów, powinieneś zakończyć dany argument polecenia po etykiecie (jeśli w ogóle ich potrzebujesz). Np.sed -e ':a' -e 'N;$!ba' -e 'whatever'
Wildcard,

Odpowiedzi:

34

Przemyślasz to. seddomyślnie zastępuje tylko pierwszą instancję w wierszu (bez /gmodyfikatora), chociaż nadal chcesz zakotwiczyć, ponieważ nie chcesz; t tak bardzo chcesz pierwszej instancji w linii, jak tej na początku linii; i zwykle nie potrzebujesz wyraźnych akcji liniowych, których próbujesz użyć (dlaczego?).

sed 's/^" /"/'
geekozaur
źródło
Dzięki! Pomyślałem, że konieczne jest jawne zadeklarowanie akcji linii podczas pracy nad plikiem, przeczytanie o tym i po prostu ich używanie. Naprawdę się nad tym zastanawiałem, bo to nie może być prostsze i załatwia sprawę :)
Steve B.,
Kusi mnie, aby powiedzieć, że te polecenia są prawie przestarzałe; możliwe jest wykonywanie z nimi dość skomplikowanych multilinii, ale nie jest to łatwe , a teraz lepiej jest używać perla / python / ruby ​​/ cokolwiek.
geekozaur
Całkowicie nie zgadzam się z powyższym komentarzem; sedpolecenia wieloliniowe , takie jak Ni etykiety, takie jak :awcale nie są przestarzałe i przenośne i są zgodne z POSIX , w przeciwieństwie do Perl / Python / Ruby / cokolwiek. Prawdą jest jednak, że jeśli często ich potrzebujesz , powinieneś się uczyćawk .
Wildcard
2

Bardziej ogólna odpowiedź, ponieważ nie mogę skomentować odpowiedzi geekozaura - nie umieściłbyś ^ (początek linii kotwicy). Na przykład, jeśli chcesz zamienić pierwsze wystąpienie A na B, zrobiłbyś to

sed 's/A/B/'
widmo
źródło