Используя SED для замены длинной строки - но получил неопределенную замену в регулярном выражении - PullRequest
0 голосов
/ 26 августа 2018

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

@x@ 

со строкой, которую я получил из командной строки:

read test    
sed -i --backup 's/@x@/'${test}'/g' file.json README.md

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

sed: 1: "s/@x@/string test string: unterminated substitute in regular expression

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

sed не понимает строки, где строка - это серия буквенных символов. Он заменяет регулярное выражение (не строку) на «строку» с включенной обратной ссылкой (также не строку), все в пределах набора разделителей (которые ТАКЖЕ требуют осторожной обработки как в регулярном выражении, так и при замене). См. Можно ли надежно избежать метасимволов регулярных выражений с помощью sed для получения дополнительной информации.

Чтобы заменить строку другой строкой, самый простой подход состоит в том, чтобы просто использовать инструмент, который понимает строки, такие как awk:

$ cat file
before stuff
foo @x@ bar
after stuff

$ cat tst.awk
BEGIN {
    old = ARGV[1]
    new = ARGV[2]
    ARGV[1] = ARGV[2] = ""
}
s = index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+length(old)) }
{ print }

$ test='a/\t/&"b'

$ awk -f tst.awk '@x@' "$test" file
before stuff
foo a/\t/&"b bar
after stuff

Вышеописанное будет работать независимо от того, какие символы содержит test, даже переводы строки:

$ test='contains a
newline'
$ awk -f tst.awk '@x@' "$test" file
before stuff
foo contains a
newline bar
after stuff
0 голосов
/ 26 августа 2018

Проблема возникает из-за того, что вы используете одинарные кавычки.В настоящее время вы заканчиваете свой ввод за 2. одиночной кавычкой.См. Сообщение об ошибке, оно информирует вас о том, что в нем что-то отсутствует.

Если у вас есть файл со следующим содержимым:

foo @x@ foo

Чем вы можете заменить содержимое, например:с помощью следующей команды:

sed 's/@x@/bar foo bar/' foo.txt > foo2.txt

И получить:

foo bar foo bar foo

Если вам нужно передать переменную, комментарий от Гордона Дэвиссона покажет вам правильный путь.

Кстати, если вы хотите использовать опцию inplace, в моем linux вам нужно будет использовать такую ​​команду:

sed -i.old "s/@x@/${test}/" foo.txt

Но я думаю, что это может зависеть от вашей среды (mac?).

...