Использовать команду sed с переменными

Я пробовал все возможные решения, доступные в Stack Overflow и связанных с ним веб-сайтах, но не нашел решения. Я потратил достаточное количество времени на эту проблему и, наконец, опубликовал этот вопрос.

Я хочу использовать команду sed с переменными оболочки. Мой скрипт довольно прост:

 ## string to replace is the text after comma in the variable pc. to_replace=${pc#*,} echo $to_replace ##text to be replaced by the following line replace_with="PARTITIONED BY ($pc1);" echo $replace_with ## use sed command to replace. sed "s@$to_replace@$replace_with@" $entry ## $entry is the variable that contains the file name 

Две команды echo дают следующие выходы соответственно:

 PARTITIONEDED BY (date_key ); ## the text I want to be replaced PARTITIONED BY ( date_key int ); ## the text I want to replace with 

Я либо получаю сообщение об ошибке:

 sed: -e expression #1, char 2: unterminated `s' command 

или текст вообще не заменяется.

Кто-то, пожалуйста, помогите. Я использую Centos 6 (если это имеет значение). Заранее спасибо!

 sed: -e expression #1, char 2: unterminated `s' command 

В сообщении об ошибке говорится, что ошибка возникает во втором символе, что кажется любопытным. Я могу воспроизвести это, поставив новую строку в начале первой переменной:

 $ a=$'\nfoo' $ b='bar' $ sed "s@$a@$b@" sed: -e expression #1, char 2: unterminated `s' command 

Неожидаемая новая строка завершает команду sed. Помещение новой строки позже в a , конечно, даст ошибку для более позднего символа.

Вы уже распечатывали обе переменные ранее в скрипте, но они не цитировались, поэтому любые ведущие пробелы в них были удалены, а пробелы посередине отображались как одиночные пробелы.

Проверьте, что на самом деле содержат ваши переменные, с чем-то вроде этого:

 printf ">%s<\n" "$to_replace" printf "%q\n" "$to_replace" 

Последний – это функция Bash, которая отображает строку, указанную так, как Bash принимает в качестве входных данных. set -x также покажет, что входит в командную строку sed, но вам нужно будет заметить буквальную новую строку из ее вывода.

Итак, если есть единственная ведущая строка новой строки, вы можете удалить ее в начале скрипта:

 to_replace=${pc#*,} to_replace=${to_replace#$'\n'} 

(Вы могли бы объединить их в одну, но отдельные шаги, даже если новая строка не существует.)

Попробуй это

 sed -i -e "s@$to_replace@$replace_with@g" "$entry" 

где

  • -i означает заменить «на месте», если вы не используете -i заменить будет на стандартный вывод.