2012-08-29 13 views
29

To, co robię (uproszczony przykład):Co jest nie tak z moim wyrażeń regularnych w GNU sed?

gsed -i -E 's/^(?!foo)(.*)$/bar\1/' file.txt 

próbuję umieścić bar przed każdym wierszu, który nie zaczyna się foo. To jest błąd:

gsed: -e expression #1, char 22: Invalid preceding regular expression 

Co jest nie tak?

+0

możliwy duplikat http://stackoverflow.com/questions/2086450/pcre-regex-to-sed-regex – hostmaster

+1

proszę zaktualizować wybraną odpowiedź, jeśli to możliwe. [This] (http://stackoverflow.com/a/12178023/131120) pokazuje, że faktycznie można osiągnąć to samo z sed. – erikbwork

Odpowiedz

36

O ile mi wiadomo, sed nie ma ani patrzenia w przyszłość, ani patrzenia za siebie. Przełącz na bardziej wydajny język o podobnej składni, na przykład perl.

+14

Prosta konwersja 'sed' na' perl' dla odniesienia: 'sed 's/before/after/g'/my/file' =>' cat/my/file | perl -ne/s/before/after/g; print; '' – Batandwa

+4

@ Batatwa http://www.smallo.ruhr.de/award.html – ceving

+7

@ Batatwa Używanie kotów i przewodów rurowych w perlu jest zbędne. Po prostu użyj 'perl -pi -e 's/before/after/g'/my/file'. – ypid

6

Używasz zgodnej z Perl składni wyrażeń regularnych (PCRE), która nie jest obsługiwana przez GNU sed. Powinieneś przepisać swoje wyrażenie regularne zgodnie z SED Regular-Expressions lub zamiast tego użyć perla.

83
sed -i '/^foo/! s/^/bar/' file.txt 
  • -i => zmienić plik w miejscu
  • /^foo/! => wykonać tylko kolejną akcję na liniach nie (!) zaczynających się foo (^foo)
  • s/^/bar/ => zmiany początek linii do baru  
+3

Bardzo ładne rozwiązanie. Nie ma potrzeby śledzenia wstecznego. Po prostu użyj funkcji, które już posiada sed. –

+7

To jest w porządku dla zakotwiczonego wyrażenia takiego jak '^ foo', ale niestety nie rozciąga się na ogólny przypadek negatywnego uprzedzania w dowolnym miejscu wzorca. – tripleee

Powiązane problemy