
Я перепробовал все возможные решения, доступные на 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 (если это имеет значение). Заранее спасибо!
решение1
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'}
(Вы можете объединить их в один, но отдельные шаги работают даже при отсутствии новой строки.)
решение2
Попробуй это
sed -i -e "s@$to_replace@$replace_with@g" "$entry"
где
-i
означает замену «на месте». Если не использовать, то-i
замена будет на стандартном выводе.