Незавершенная команда `s'

Другие ответы подходят для примера (файл в формате CSV*(двоеточие -разделенные значения ), искомая строка -будет первым полем, желаемый результат - второе поле ), но ни одно из этих ограничений / условий на самом деле указано в вопросе. И, пока вопрос требует команды который исключает строки, которые начинаются с комментария, это, вероятно, не то, чего на самом деле хочет ОП. (Как насчет строки типа unwanted line:blah:blah #test, который содержитtestв комментарии ? )Ответ, который хочет ОП,

grep '^[^#]*test' /etc/oratab

или

grep "^[^#]*$DBNAME" /etc/oratab

, который ищет строку, где появляется test, и все символы перед ним не являются #.

Как обычно, ссылки на переменные оболочки всегда должны заключаться в кавычки. (например, "$DB_NAME"и "$env_var"), если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете. И, , как указывает Стефан Шазела , если $DBNAMEвыглядит как не -тривиальное регулярное выражение (например, содержит ., *или []), возможны нежелательные результаты.

0
26.04.2020, 22:50
2 ответа

Ваш grep, вероятно, соответствует более чем одному имени файла, что дает значение в $res, содержащее новые строки. GNU sedбудет жаловаться точно так же, как вы описываете, при использовании строки замены, которая содержит буквальные символы новой строки.

Не используйте grepдля фильтрации вывода ls. Если вы хотите, чтобы все имена в текущем каталоге соответствовали шаблону *.pub, используйте

filenames=( *.pub )

Это создаст массив, содержащий все имена, соответствующие данному шаблону.

Тогда:

sed 's/\(@demo_project_users = \).*/\1'"${filenames[*]%.pub}"'/g' example.conf

Расширение "${filenames[*]%.pub}"расширится до одной строки, состоящей из имен файлов в массиве filenames, разделенных пробелами (или любым другим первым символом $IFS; пробел по умолчанию )и с удаленной строкой суффикса .pub.

Это бит "${filenames[*]}", который расширяется до строки, разделенной пробелом -, а бит %.pubудаляет суффикс .pubиз каждого имени файла.

5
19.03.2021, 02:25

Подстановка $resв команду выполняется оболочкой. Если в значении есть косая черта, sed не может узнать, что это не конечный маркер для команды s. Точно так же sed интерпретирует любую обратную косую черту или амперсанд в $resкак специальный символ.

Если обратная косая черта и амперсанд не могут появляться в $resи есть другой символ, который, как вы знаете, также не может появляться, используйте этот символ в качестве разделителя. Например:

sed  "s~@demo_project_users =.*~$res~g" example.conf

Также можно заключать специальные символы в кавычки, добавляя перед ними обратную косую черту.

quoted_res=$(printf %s "$res" | sed 's/[\\\/&]/\\&/g')
sed  "s/@demo_project_users =.*/$quoted_res/g" example.conf
0
19.03.2021, 02:25

Теги

Похожие вопросы