zamień n-te wystąpienie ciągu w każdym wierszu pliku tekstowego

15

Mam duże pliki tekstowe z ciągami rozdzielanymi spacjami (2-5). Ciągi mogą zawierać „” lub „-”. Chciałbym zastąpić powiedzmy drugie miejsce rurą.

Jaka jest najlepsza droga?

Korzystając z sed, myślałem o tym:

sed -r 's/(^[a-z'-]+ [a-z'-]+\b) /\1|/' filename.txt

Jakieś inne / lepsze / prostsze pomysły?

dnkb
źródło

Odpowiedzi:

22

Możesz dodać liczbę na końcu polecenia zastępowania. Na przykład następujące zastąpi drugie wystąpienie oldciągu neww każdej linii file:

sed 's/old/new/2' file

Zamiast proponowanego rozwiązania możesz użyć:

sed 's/ /|/2'

Aby uzyskać więcej informacji, zobacz np. Ten samouczek sed .

mrucci
źródło
2
Z sedpliku informacyjnego: „Uwaga: standard POSIX nie określa, co powinno się stać, kiedy g' and NUMBER modifiers, and currently there is no widely agreed upon meaning across miksujesz implementacje sed”. W przypadku GNU „sed” interakcja jest zdefiniowana jako: zignoruj ​​dopasowania przed NUMBER, a następnie dopasuj i zamień wszystkie dopasowania od NUMBER dnia ”.
Wstrzymano do odwołania.
Pliki informacyjne ... Nienawidzę ich. W każdym razie usunąłem niejednoznaczną część. Dobry komentarz, +1.
mrucci
1
Dzięki, Mrucci i Dennis. Myślałem, że musi być coś prostego.
dnkb
Wydaje się, że każdy problem z manipulacją tekstem rozwiązuję sed. Nie jestem pewien, czy powinienem ci podziękować za uczynienie mnie sedjeszcze bardziej użytecznym, ale i tak to zrobię. ;)
Jamie,
1

Próbowałeś swojej wersji? Zadziałało? Ponieważ uważam, że jest to w zasadzie dobry pomysł. Zrobiłbym jednak nieco inaczej:

sed -re 's/^([^ ]+ +[^ ]+) /\1|/'

Spowoduje to zaakceptowanie dowolnych znaków w słowie, które nie jest spacją, i zaakceptuje więcej niż jedną spację między dwoma pierwszymi słowami.

petersohn
źródło