¿Cómo puedo desactivar la variable de interpolación con el Perl de sustitución de operador?
Pregunta
Estoy tratando de reemplazar una línea en particular en un archivo de texto en máquinas virtuales.Normalmente, esta es una simple línea con Perl.Pero me encontré con un problema cuando la sustitución lado era un símbolo que contiene un VMS camino.Aquí está el archivo y lo he intentado:
Contenido de file1.txt:
foo
bar
baz
quux
El intento de sustituir la 3ª línea:
$ mysub = "disk$data1:[path.to]file.txt"
$ perl -pe "s/baz/''mysub'/" file1.txt
Se obtiene el siguiente resultado:
foo
bar
disk:[path.to]file.txt
quux
Parece Perl fue el afán y se sustituye el $data1
parte de la ruta con el contenido de una inexistente variable (es decir, nada).La ejecución con el depurador confirmado que.Yo no la oferta /e
, pensé en Perl sólo debe reemplazar el texto tal como está.Es allí una manera de conseguir Perl para hacer eso?
(Tenga en cuenta también que puedo reproducir un comportamiento similar en la línea de comandos de linux.)
Solución
Con la combinación justa de las comillas las comillas dobles y usted puede conseguir allí:
Vamos a crear una estrecha concatenación de "cadena" + 'sustituto símbolo" + "de la cadena".Las dos cadenas entre comillas dobles contener comillas simples para el sustituto.Artificial...pero funciona.
$ perl -pe "s'baz'"'mysub'"'" file1.txt
Eso es un DCL nivel de la solución.
Para un Perl de la solución, el uso de la q()
operador para un no-interpolados cadena y lo ejecuta.Cosas el símbolo dentro del paréntesis el uso de simples DCL sustitución.Este es mi favorito porque (casi) no tiene sentido para mí y no llegar demasiado confuso con las comillas.
$ perl -pe "s/baz/q(''mysub')/e" file1.txt
Otros consejos
Como ruakh descubierto al leer mi comentario, el problema de perl de interpolación puede ser resuelto mediante el acceso a la %ENV
hash, en lugar de usar una variable de shell:
perl -pwe "s/baz/$ENV{mysub}/" file1.txt
Agregó -w
porque yo no creo en el no uso de warnings
incluso en los chistes.
No he visto un sistema VMS en décadas, pero ...escapar de su sigilo?
$ mysub = "disk\$data1:[path.to]file.txt"
o tal vez
$ mysub = "disk\\$data1:[path.to]file.txt"
?
Para sh
o un derivado, yo uso la
perl -pe'BEGIN { $r = shift(@ARGV) } s/baz/$r/' "$mysub" file1.txt
De lo contrario, usted tiene que de alguna manera encubierta el valor de mysub
en un Perl literal de cadena.Que sería más complicado.Encontrar el equivalente de su shell.
Editar por OP:
Sí, esto funciona.El VMS es equivalente
perl -pe "BEGIN { $r = shift(@ARGV) } s/baz/$r/" 'mysub' file1.txt
Tienes que escapar de los $
con \$
.De lo contrario, Perl ve una variable de referencia y sustituye la cadena $data1
con el contenido de $data1
antes de la expresión regular se evalúa.Como no definir $data1
es, por supuesto, vacía.
Usted puede utilizar el código siguiente :
$ mysub='disk\$data1:[path.to]file.txt'
$ perl -pe 's/baz/'$mysub'/' FILE
foo
bar
disk$data1:[path.to]file.txt
quux
Usted podría tratar de usar un nombre lógico en lugar de un DCL símbolo:
$ define mysub "disk$data1:[path.to]file.txt"
$ $ perl -pe "s/baz/mysub/" file1.txt
El uso de sed.
Sed no voy a tratar de interpolar $data1
como una variable, así que usted debe conseguir lo que desea.
$ sed -e "s/baz/''mysub'/" file1.txt