Проблема с передачей переменной в sed

Заменить IP без условий можно с помощью:

perl -pe 's!(\d+(\.\d+){3})! $1 =~s/\d/a/gr !ge' 

Пояснение: заменить IP на результат (заменить цифры на "a")

Чтобы защитить IP после "SpecialWord", пометьте IP знаком "#" (и уберите его в конце)

perl -pe 's/"SpecialWord"\s*\d+/$&#/; 
          ..... 
          s/#//'

Все вместе:

perl -pe 's/"SpecialWord"\s*\d+/$&#/; 
          s!(\d+(\.\d+){3})! $1 =~s/\d/a/gr !ge;
          s/#//'   file
4
15.12.2016, 01:25
3 ответа

Как вы упомянули, вы должны использовать двойные кавычки, потому что, когда вы используете одинарные кавычки для строк, их содержимое будет обрабатываться буквально. Но в вашем случае у вас есть комбинация шаблона и переменной. Таким образом, вы должны использовать одинарные кавычки для шаблона и двойные кавычки для переменной:

sed "$lnum"'!d' cloud.cpp
7
27.01.2020, 20:45

Если ваша переменная содержит только цифру, то, что вы сделали, правильно:

sed "$lnum!d" cloud.cpp

Для передачи оболочки в sed в целом, прочтите этот ответ .


Итак, в этом случае вы сделали это правильно, но это все еще не работает. Это связано с вашей оболочкой, которая, вероятно, bash , zsh или csh . Эти оболочки поддерживают расширение истории, которое обозначается ! (Эта функция является оригинальной из csh и позже скопирована bash и zsh ).

В bash , zsh расширение истории включено по умолчанию в интерактивном сеансе и будет выполняться в двойных кавычках.

В zsh :

$ seq 10 | sed "10!d" # <-- press enter
$ seq 10 | sed "10dash"

as dash - моя последняя команда в истории, начиная с d .

В bash :

$ seq 10 | sed "10!d"
bash: !d": event not found

, поскольку у меня нет никакой команды в истории bash, начните с d .

Вы можете отключить раскрытие истории:

set +H

или:

set +o histexpand

в bash и:

set -K

или:

setopt nohistexpand

в zsh .


Для большей переносимости, не полагаясь на параметры оболочки, вы всегда можете сделать:

sed "$lnum"\!d cloud.cpp

, что заставит вашу оболочку обработать ! буквально.

9
27.01.2020, 20:45

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


Вы запускаете расширение истории в оболочке. Из man bash :

! String

Ссылка на самую последнюю команду, предшествующую текущей позиции в списке истории, начиная со строки.

Самое странное в этом то, что:

Если включено, раскрытие истории будет выполняться, если не будет ! , появляющееся в двойных кавычках, экранируется с помощью обратной косой черты. Обратная косая черта перед ! не удаляется.

Поэтому я думаю, что цитирование их по отдельности, вероятно, является лучшим решением:

sed "$lnum"'!d' cloud.cpp

Это также работает (сохраняя символ):

sed "$lnum"\!d cloud.cpp

Это также работает (если вы предпочитаете двойные кавычки):

sed "$lnum""!""d" cloud.cpp
4
27.01.2020, 20:45

Теги

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