Почему в этой замене регулярных выражений теряется кавычка? - PullRequest
0 голосов
/ 23 сентября 2018

Почему экранирование двойных кавычек теряется в этом случае?

$ cat foo.txt   
This is a \"very good\" text worth AMOUNT dollars    
$ cat full_story.txt   
This is about money:  
STORY  

Тестирование со следующим:

VAR=$(cat foo.txt)                                                                                         
TOTAL=$(cat full_story.txt)  
echo "$TOTAL" | perl -pe "s/STORY/$VAR/g"  

Результат:

This is about money:  
This is a "very good" text worth AMOUNT dollars  

Экранирование двойных кавычек потеряно.Я ожидал:

This is about money:  
This is a \"very good\" text worth AMOUNT dollars  

Как я могу сохранить побег?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Ваш код страдает от ошибки внедрения кода .В частности, вы пытаетесь сгенерировать код Perl из оболочки, но терпите неудачу в этом.

Вы передаете в Perl следующее:

s/STORY/This is a \"very good\" text worth AMOUNT dollars/g

Вы должны передать следующее:

s/STORY/This is a \\"very good\\" text worth AMOUNT dollars/g

Чтобы правильно сгенерировать код Perl, вам понадобится что-то вроде следующего:

perl -pe's/STORY/'"$( printf %s "$VAR" | sed 's/\W/\\&/g' )"'/'

Это передает Perl следующее (что тоже хорошо):

s/STORY/This is a \\\"very good\\\" text worth AMOUNT dollars/g

Однако гораздо проще избежать генерации кода Perl.Существует три основных способа передачи информации в Perl без использования STDIN или внешнего хранилища.

  • Аргументы

    perl -pe'BEGIN { $VAR = shift(@ARGV) } s/STORY/$VAR/g' -- "$VAR"
    
  • Параметры командной строки

    В полной программе вы бы использовали Getopt :: Long , но perl -s здесь подойдет.

    perl -spe's/STORY/$VAR/g' -- -VAR="$VAR"
    
  • Переменные среды

    VAR="$VAR" perl -pe's/STORY/$ENV{VAR}/g'
    
0 голосов
/ 23 сентября 2018

Проблема в том, что perl анализирует экранирование обратной косой черты в явной строке замены (не в переменной perl), и, следовательно, \" анализируется в ".Например:

$ echo "A STORY" | perl -pe 's/STORY/\"Hello\"/'
A "Hello"

(Обратите внимание, что переменная Bash $VAR становится не perl переменной $VAR, а скорее константной строкой.) Таким образом, вы должны избегать обратной косой черты, как это вконстантная строка:

$ echo "A STORY" | perl -pe 's/STORY/\\"Hello\\"/' 
A \"Hello\"

Вы можете обойти эту проблему, передав переменную Bash $VAR в perl переменную $VAR, используя переключатель -s в perl как это:

echo "$TOTAL" | perl -spe 's/STORY/$VAR/g' -- -VAR="$VAR"

Ouput :

This is about money:  
This is a \"very good\" text worth AMOUNT dollars

Объяснение:

  • -s включает синтаксический анализ переключателей, определенных пользователем, в командной строке perl.Любой найденный там переключатель удаляется из @ARGV и устанавливает соответствующую переменную в программе Perl.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...