2012-08-29 8 views
29

Questo è quello che sto facendo (esempio semplificato):Cosa c'è di sbagliato con il mio lookahead regex in GNU sed?

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

che sto cercando di mettere bar davanti ad ogni riga che non inizia con foo. Questo è l'errore:

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

Cosa c'è che non va?

+0

possibile duplicato di http://stackoverflow.com/questions/2086450/pcre-regex-to-sed-regex – hostmaster

+1

si prega di aggiornare la risposta scelta se possibile. [Questo] (http://stackoverflow.com/a/12178023/131120) mostra che è effettivamente possibile ottenere lo stesso con sed. – erikbwork

risposta

36

Per quanto ne so, lo sed non ha né il look-ahead né il look-behind. Passa a una lingua più potente con sintassi simile, ad esempio perl.

+14

Una semplice conversione da 'sed' a' perl' per riferimento: 'sed 's/prima/dopo/g'/mio/file' =>' cat/mio/file | perl -ne 's/before/after/g; print; '' – Batandwa

+4

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

+7

@Batandwa L'uso di cat e piping in perl è ridondante. Basta usare 'perl -pi -e 's/prima/dopo/g'/mio/file'. – ypid

6

Si utilizza la sintassi di espressione regolare compatibile perl (PCR) che non è supportata da GNU sed. Dovresti riscrivere la tua espressione regolare secondo SED Regular-Expressions o usare perl.

83
sed -i '/^foo/! s/^/bar/' file.txt 
  • -i => cambiamento il file in luogo
  • /^foo/! => solo eseguire l'azione successiva su linee non (!) iniziano con foo (^foo)
  • s/^/bar/ => cambiamento l'inizio della linea a barra  
+3

Soluzione molto bella. Non è necessario il tracciamento posteriore. Basta usare la funzionalità che ha già sed. –

+7

Questo va bene per un'espressione ancorata come '^ foo', ma sfortunatamente non si estende al caso generale di lookahead negativo ovunque in un pattern. – tripleee