Jak wstawić nową linię przed wzorcem w linii?
Na przykład spowoduje to wstawienie nowej linii za wzorcem wyrażenia regularnego.
sed 's/regex/&\n/g'
Jak mogę zrobić to samo, ale przed wzorem?
Biorąc pod uwagę ten przykładowy plik wejściowy, wzorcem do dopasowania jest numer telefonu.
some text (012)345-6789
Powinno stać się
some text
(012)345-6789
sed '/regex/G'
Odpowiedzi:
Działa to w
bash
izsh
, przetestowane w systemie Linux i OS X:Ogólnie rzecz biorąc, for,
$
po którym następuje literał ciągu w pojedynczych cudzysłowach,bash
wykonuje podstawienie odwrotnym ukośnikiem w stylu C, np.$'\t'
Jest tłumaczone na literał tabulacji. Dodatkowo sed chce, aby twój literał nowej linii był chroniony przed odwrotnym ukośnikiem, stąd\
poprzednia$
. I wreszcie, sam znak dolara nie powinien być cytowany, aby był interpretowany przez powłokę, dlatego zamykamy cudzysłów przed znakiem$
i otwieramy go ponownie.Edycja : zgodnie z sugestią w komentarzach @ mklement0, działa to również:
Oto co się tutaj dzieje: całe polecenie sed jest teraz napisem w stylu C, co oznacza, że odwrotny ukośnik, którego sed wymaga, aby został umieszczony przed literałem nowego wiersza, powinien być teraz poprzedzony innym lewym ukośnikiem. Chociaż bardziej czytelne, w tym przypadku nie będziesz w stanie dokonać podstawień łańcucha powłoki (bez ponownego uczynienia go brzydkim).
źródło
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
. Zwróć uwagę na dwa pojedyncze cudzysłowy po \ n. Pierwsza zamyka$
sekcję „ ”, tak że nie ma wpływu na pozostałą część linii. Bez tych cudzysłowów \ 2 został zignorowany.sed $'s/regexp/\\\n/g'
, co poprawia czytelność - jedyne zastrzeżenie jest to, że wtedy trzeba podwoić wszystkie dosłownych\
znaków.Niektóre inne odpowiedzi nie działały w mojej wersji seda. Zmiana pozycji
&
i\n
zadziałała.Edycja: Wydaje się, że to nie działa w systemie OS X, chyba że zainstalujesz
gnu-sed
.źródło
brew install gnu-sed
następniegsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
W sedzie nie można łatwo dodawać nowych linii do strumienia wyjściowego. Musisz użyć linii kontynuacji, co jest niezręczne, ale działa:
Przykład:
Zobacz tutaj po szczegóły. Jeśli chcesz czegoś mniej niezręcznego, możesz spróbować użyć
perl -pe
z grupami dopasowań zamiast sed:$1
odnosi się do pierwszej dopasowanej grupy w wyrażeniu regularnym, gdzie grupy są podane w nawiasach.źródło
perl -pi -e 's/(.*)/\n$1/' foo
s
wywołania funkcji (w przeciwieństwie do implementacji GNU Sed, która tak robi) . Powyższa odpowiedź działa w przypadku obu implementacji; przegląd wszystkich różnic znajduje się tutaj .Na moim Macu następujące wstawia pojedyncze „n” zamiast nowej linii:
To zastępuje nową linią:
źródło
sed -i '' -e ...
i miałem problemy z^M
daszkiem M (ctrl + m) podczas zapisywania do pliku. Skończyło się na tym, że użyłem Perla z tymi samymi parametrami.\n
).echo...
i nowej linii), że zrobiłem to w vimie.sed "s/regexp/`echo`/g"
- spowoduje to powstanie pojedynczego LF zamiast LF-CR`echo`
da w wyniku pusty ciąg , ponieważ podstawienia poleceń niezmiennie przycinają wszystkie końcowe znaki nowej linii. Nie ma sposobu, aby użyć podstawiania poleceń do bezpośredniego wstawienia pojedynczego\n\r
znaku nowej linii (a wstawienie - tj. Dodatkowej litery CR - jest okropnym pomysłem).źródło
$'\n'
polega na powłoce w celu wygenerowania nowej linii. Takie rozwiązania mogą nie być przenośne. Ten jest. Oczywiście jest to również duplikat drugiego przykładu w odpowiedzi tgamblin z 2009 roku.W tym przypadku nie używam seda. Używam tr.
Spowoduje to pobranie przecinka i zastąpienie go znakiem powrotu karetki.
źródło
cat Somefile | tr ',' '\n'
YMMVMożesz używać jednowierszowych perl, podobnie jak w sedzie, z zaletą pełnego wsparcia wyrażeń regularnych w perlu (które jest znacznie potężniejsze niż to, co dostajesz z sed). Występuje również bardzo mała różnorodność między platformami * nix - perl to generalnie perl. Możesz więc przestać martwić się o to, jak sprawić, by wersja seda w Twoim systemie robiła to, co chcesz.
W takim przypadku możesz to zrobić
-pe
umieszcza perl w pętli "wykonaj i wydrukuj", podobnie jak normalny tryb działania seda.'
cytuje wszystko inne, aby powłoka nie przeszkadzała()
otoczenie wyrażenia regularnego jest operatorem grupowania.$1
po prawej stronie zamiany wypisuje wszystko, co zostało dopasowane w tych pasmach.Wreszcie
\n
jest nowa linia.Niezależnie od tego, czy używasz nawiasów jako operatora grupującego, musisz uciec przed wszystkimi nawiasami, które próbujesz dopasować. Zatem wyrażenie regularne pasujące do wzorca wymienionego powyżej byłoby czymś w rodzaju
\(
lub\)
dopasowuje dosłowny paren i\d
dopasowuje cyfrę.Lepszy:
Wyobrażam sobie, że możesz dowiedzieć się, co robią liczby w nawiasach klamrowych.
Dodatkowo możesz użyć separatorów innych niż / dla swojego wyrażenia regularnego. Więc jeśli chcesz dopasować / nie musisz od tego uciekać. Każde z poniższych jest odpowiednikiem wyrażenia regularnego na początku mojej odpowiedzi. Teoretycznie można zastąpić standard (y) dowolnym znakiem .
Kilka myśli końcowych.
używanie
-ne
zamiast-pe
działa podobnie, ale nie drukuje automatycznie na końcu. Może być przydatne, jeśli chcesz drukować samodzielnie. Na przykład, oto grep-alike (m/foobar/
to dopasowanie wyrażenia regularnego):Jeśli uważasz, że radzenie sobie z nowymi liniami jest kłopotliwe i chcesz, aby było to dla Ciebie magiczne, dodaj
-l
. Nie jest to przydatne dla OP, który pracował z nowymi liniami.Dodatkowa wskazówka - jeśli masz zainstalowany pakiet pcre, jest on dołączony do zestawu
pcregrep
, który używa wyrażeń regularnych zgodnych z Perlem.źródło
Hmm, po prostu znaki nowej linii ze znakami ucieczki wydają się działać w nowszych wersjach
sed
(mam GNU sed 4.2.1),źródło
działał dobrze na El Captitan ze
()
wsparciemźródło
Aby wstawić znak nowej linii do strumienia wyjściowego w systemie Linux, użyłem:
Gdzie
file1
było:Przed wymianą seda na miejscu oraz:
Po wymianie seda na miejscu. Zwróć uwagę na użycie
\\\n
. Jeśli wzorce mają"
wewnątrz, ucieknij za pomocą\"
.źródło
sed
wstawia\n
zamiast LF, ponieważ pobiera\\n
parametr z powłoki. --- Ten kod działa:sed -i "s/def/abc\ndef/" file1
. ---GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS wersja 6.4 / Ubuntu 12.04.3).w sed możesz odwołać się do grup w swoim wzorcu za pomocą "\ 1", "\ 2", .... więc jeśli szukany wzorzec to "WZÓR" i chcesz wstawić przed nim "PRZED" , możesz użyć, sans ucieczki
to znaczy
źródło
Możesz to również zrobić za pomocą awk, używając
-v
do podania wzorca:Sprawdza, czy linia zawiera podany wzorzec. Jeśli tak, dodaje nowy wiersz na początek.
Zobacz podstawowy przykład:
Zauważ, że wpłynie to na wszystkie wzorce w linii:
źródło
1
jest używane w Awk jako skrót od{print $0}
. Powodem jest to, że każdy warunek, który ma wartość True, wyzwala domyślne działanie Awk, które polega na wydrukowaniu bieżącego rekordu.To działa w MAC dla mnie
Dono, czy jest idealny ...
źródło
Po przeczytaniu wszystkich odpowiedzi na to pytanie, nadal zajęło mi wiele prób, aby uzyskać poprawną składnię poniższego przykładowego skryptu:
Skrypt dołącza nowy wiersz,
\n
po którym następuje kolejny wiersz tekstu, na końcu pliku za pomocą jednegosed
polecenia.źródło
\ 0 to null, więc twoje wyrażenie jest zastępowane przez null (nic), a następnie ...
\ n jest nową linią
Na niektórych odmianach Uniksa nie działa, ale myślę, że to rozwiązanie twojego problemu.
źródło
W vi w Red Hacie mogłem wstawić powrót karetki używając tylko znaku \ r. Uważam, że to wewnętrznie wykonuje „ex” zamiast „sed”, ale jest podobny, a vi może być innym sposobem na zbiorcze edycje, takie jak poprawki kodu. Na przykład. Otaczam wyszukiwane hasło instrukcją if, która nalega na powrót karetki po nawiasach klamrowych:
Zwróć uwagę, że kazałem też wstawić kilka zakładek, aby lepiej się wyrównać.
źródło