2013-05-24 2 views
17
$ perl --version 
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi 

$ echo -e "foo\nbar" > baz.txt 
$ perl -p -e 's/foo\nbar/FOO\nBAR/m' baz.txt 
foo 
bar 

Come posso far funzionare questo ricambio?Come posso cercare e sostituire su più righe con Perl?

+1

Prova ad aggiungere il flag 'g':' 's/foo \ nbar/FOO \ nBAR/gm''. – Jerry

+3

@Jerry no, l'opzione 'g' è per il comportamento globale e non è rilevante per il mio problema. –

+0

debitamente indicato @GabeKopley – Jerry

risposta

38

È possibile utilizzare l'interruttore -0 per modificare il separatore di ingresso:

perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt 

-0777 imposta il separatore undef, -0 sola imposta che a \0 che potrebbe funzionare per file di testo che non contengono il byte null.

Si noti che /m è inutile in quanto la regex non contiene ^$.

+1

Molto meglio del mio. Non sono abituato all'intervallo '-0', ma in questo caso si adatta perfettamente. ** + 1 ** per quello. – Birei

+1

'-0' imposta' $/'a' "\ 000" 'e' -0777' su 'undef', ma entrambi eseguono lo slurp dei file. : o –

+2

@ Сухой27, no. '-0' scava solo il file se non contiene caratteri NUL. I file di testo normalmente non contengono quei caratteri. Quindi, per i file di testo, in genere non fa la differenza, ma se si desidera eseguire lo slurp del file indipendentemente da ciò che può contenere, è "-0777" che si desidera. '-0' è più per l'elaborazione dell'output di' find -print0' o 'grep -lZ' (NUL delimited records). Confronta 'printf 'a \ 0b \ 0' | perl -l -0 -ne 'print $.' 'con' printf 'a \ 0b \ 0' | perl -l -0777 -ne 'print $.' ' –

5

Ha a che fare con lo switch -p. Legge input una riga alla volta. Quindi non puoi eseguire un'espressione regolare contro una nuova riga tra due righe perché non corrisponderà mai. Una cosa che puoi fare è leggere tutte le variabili di modifica dell'input $/ e applicarle l'espressione regolare. Un modo:

perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt 

Produce:

FOO 
BAR