Como posso desabilitar a variável de interpolação com o Perl de substituição de operador?

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

  •  12-12-2019
  •  | 
  •  

Pergunta

Estou tentando substituir uma determinada linha em um arquivo de texto em VMS.Normalmente, esta é uma simples linha com Perl.Mas eu tive um problema quando a substituição lado era um símbolo contém uma VMS caminho.Aqui está o arquivo e o que eu tentei:

Conteúdo file1.txt:

foo
bar
baz
quux

Tentativa de substituto de 3ª linha:

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

Produz a seguinte saída:

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

Parece que o Perl foi overeager e substituiu o $data1 parte do caminho com o conteúdo de um inexistente variável (isto é, nada).Execução com o depurador confirmou que.Eu não fornecimento /e, então eu pensei em Perl deve apenas substituir o texto como está.Existe uma maneira de obter o Perl para fazer isso?

(Note também que eu possa reproduzir um comportamento semelhante no linux a linha de comando.)

Foi útil?

Solução

Com a mistura certa de aspas e aspas duplas você pode chegar lá:

Criamos um apertado concatenação de "cadeia de caracteres" + 'substituto símbolo" + "cadeia".As duas seqüências de caracteres entre aspas conter aspas simples para o substituto.Teceu...mas funciona.

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

Essa é uma DCL nível de solução.

Para um Perl solução, use o q() operador para um não-interpolados cadeia e executar.Coisas que o símbolo no parens usando simples DCL substituição.Este é o meu favorito, porque (quase) faz todo o sentido para mim, e não ficar muito confuso com aspas.

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

Outras dicas

Como ruakh descobriu ao ler o meu comentário, o problema do perl de interpolação podem ser resolvidos por acessar o %ENV hash ao invés de usar uma variável de shell:

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

Adicionado -w porque eu não acredito em não warnings mesmo em one-liners.

Ainda não vi um sistema VMS em décadas, mas ...escapar de seu brasão?

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

ou talvez

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

?

Para sh ou um derivado, eu usaria

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

Caso contrário, você precisa de alguma forma de converter o valor de mysub em um Perl de seqüência de caracteres literal.Que seria mais complicado.Encontrar o equivalente para o seu shell.

Editar pelo OP:

Sim, isso funciona.O VMS equivalente é

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

Você tem que escapar do $ com \$.Caso contrário, Perl vê uma variável de referência e substitui a cadeia $data1 com o conteúdo de $data1 antes de regular a expressão é avaliada.Como você não definir $data1 é, claro, vazio.

Você pode usar o seguinte código :

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

Você pode tentar usar um nome lógico, em vez de uma DCL símbolo:

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

Usar o sed.

Sed não tente interpolar $data1 como uma variável, então você deve obter o que deseja.

$ sed -e "s/baz/''mysub'/" file1.txt
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top