Come posso disabilitare l'interpolazione variabile con l'operatore di sostituzione perl?

StackOverflow https://stackoverflow.com//questions/12678519

  •  12-12-2019
  •  | 
  •  

Domanda

Sto cercando di sostituire una linea particolare in un file di testo su VMS.Normalmente, questo è un semplice unico rivestimento con Perl.Ma ho corso un problema quando il lato sostitutivo era un simbolo contenente un percorso VMS.Ecco il file e ciò che ho provato:

Contenuto di file1.txt:

foo
bar
baz
quux
.

Tentativo di sostituire la 3a riga:

$ mysub = "disk$data1:[path.to]file.txt"
$ perl -pe "s/baz/''mysub'/" file1.txt
.

Comporta la seguente uscita:

foo
bar
disk:[path.to]file.txt
quux
.

Sembra che Perl sia stato percorato e sostituito la parte $data1 del percorso con il contenuto di una variabile inesistente (cioè, niente).In esecuzione con il debugger lo ha confermato.Non ho fornito /e, quindi pensavo che Perl debba semplicemente sostituire il testo AS-è.C'è un modo per ottenere Perl per farlo?

(nota anche che posso riprodurre un comportamento simile alla riga di comando Linux.)

È stato utile?

Soluzione

Con il giusto mix di citazioni e doppie citazioni che puoi arrivare:

Creiamo una concatenazione stretta della "stringa" + "Simbolo sostitutivo" + "String". Le due doppie stringhe quotate contengono virgolette singole per il sostituto. Concetto ... Ma funziona.

$ perl -pe "s'baz'"'mysub'"'" file1.txt
.

Questa è una soluzione di livello DCL.

Per una soluzione perl, utilizzare l'operatore q() per una stringa non interpolata ed eseguirlo. Imparare il simbolo nella parente usando una semplice sostituzione DCL. Questo è il mio preferito perché (quasi) ha senso per me e non è troppo confuso con citazioni.

$ perl -pe "s/baz/q(''mysub')/e" file1.txt
.

Altri suggerimenti

come Ruakh scoperto quando si legge il mio commento, il problema dell'interpolazione Perl può essere risolto accedendo al %ENV Hash, piuttostoche usare una variabile shell:

perl -pwe "s/baz/$ENV{mysub}/" file1.txt
.

Aggiunto -w perché non credo in non usare warnings anche in one-Liner.

Non ho nemmeno visto un sistema VMS in decenni, ma ... Escape Your Sigil?

$ mysub = "disk\$data1:[path.to]file.txt"
.

o forse

$ mysub = "disk\\$data1:[path.to]file.txt"
.

?

per sh o un derivato, avrei usato

perl -pe'BEGIN { $r = shift(@ARGV) } s/baz/$r/' "$mysub" file1.txt
.

Altrimenti, devi in qualche modo nascosto il valore del mysub in una stringa perl letterale.Sarebbe più complicato.Trova l'equivalente per il tuo guscio.

Edit by op:

Sì, funziona.L'equivalente VMS è

perl -pe "BEGIN { $r = shift(@ARGV) } s/baz/$r/" 'mysub' file1.txt
.

Devi sfuggire al $ con \$.Altrimenti Perl vede una variabile di riferimento e sostituisce la stringa $data1 con il contenuto di $data1 prima che venga valutata l'espressione regolare.Come non hai definito $data1 è, ovviamente, vuoto.

È possibile utilizzare il seguente codice:

$ mysub='disk\$data1:[path.to]file.txt'
$ perl -pe 's/baz/'$mysub'/' FILE
foo
bar
disk$data1:[path.to]file.txt
quux
.

È possibile provare a utilizzare un nome logico invece di un simbolo DCL:

$ define mysub "disk$data1:[path.to]file.txt"
$ $ perl -pe "s/baz/mysub/" file1.txt
.

usa sed.

SED non proverà a interpolare $data1 come variabile, quindi dovresti ottenere ciò che desideri.

$ sed -e "s/baz/''mysub'/" file1.txt
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top