Как Вы сохраняете комплекс regex для нескольких, снова используют в sed?

Экспортируемые переменные несут в среду команд, выполняемых оболочкой, которая экспортировала их, в то время как неэкспортируемые переменные локальны для текущего вызова оболочки. От export страница справочника:

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

set производит текущую среду, которая включает любые локальные неэкспортируемые переменные. env используется для запуска программ в новой среде, и без аргументов произведет, какова та новая среда была бы. С тех пор env создает новую среду, только экспортируемым переменным помогают преодолеть трудности, как имеет место для любой программы, запущенной от той оболочки. Например, порождая вторую оболочку в первом (я использовал $$ представить подсказки во внутренней оболочке):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Обратите внимание, что это - переменная, это экспортируется, не только ее значение. Это означает что однажды Вы export FOO, FOO становится глобальной переменной и обнаруживается в последующих средах, даже если измененный позже:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
12
21.09.2011, 23:20
2 ответа

Можно использовать переменные оболочки:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

Я не уверен в том, под чем Вы подразумевали $i, но Вы, возможно, должны были бы поместить его вне одинарных кавычек:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'
7
27.01.2020, 19:56
  • 1
    Конечно, это работает только если sed команда вызывается от оболочки, но существует аналогичное решение почти со всеми языками программирования. (И я не думаю, что возможно использовать переменные в sed.) –  Stéphane Gimenez 21.09.2011, 21:59
  • 2
    Hrm. Пробуя это, обратные ссылки, кажется, повреждаются. s/$complicated_regex/\1/ дает ошибку при высказывании, что это - недопустимая ссылка. А-ч –  Cory Klein 21.09.2011, 22:30
  • 3
    , возможно, мой отказ, я привык к zsh подстановкам переменных. См. обновленный ответ. –  Stéphane Gimenez 21.09.2011, 22:37
  • 4
    Необходимо будет удалить привязки из переменной и поместить их в sed сценарий: sed "s/^${complicated_regex}:${complicated_regex}\$/simple-output/" my_file –  glenn jackman 21.09.2011, 23:09
  • 5
    Понятное дело! Да, я забыл проверять, что мне предоставили допустимую regex конкатенацию :-) –  Stéphane Gimenez 21.09.2011, 23:13

Самый простой способ добавить значение переменной оболочки в sed и не беспокоиться о том, как нужно будет изменить экранирование обратной косой черты для остальная часть вашего сценария sed заключается в том, чтобы поместить все в одинарные кавычки , кроме переменной, и поместить это в двойные кавычки.

Все следующие примеры кода предполагают: VALUE = 'foo \ ([az] \ + \)'

Следующий неработающий код не работает, потому что переменная VALUE не раскрывается:

sed 's/"${VALUE}"/foo happy \1/' test.txt

Следующий неработающий код не работает, потому что обратная косая черта на \ 1 съедается оболочкой (потому что она заключена в двойные кавычки, а не в одинарные) перед sed когда-либо видит это:

sed "s/${VALUE}/foo happy \1/" test.txt

Следующий код работает, как ожидалось:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

Следующий код также работает:

sed "s/${VALUE}/foo happy \\1/" test.txt

То же самое:

sed s/"${VALUE}"/foo\ happy\ \\1/ test.txt

Но зачем усложнять? Одиночные кавычки вокруг сценария sed делают все намного понятнее, особенно для гуру, не связанного со сценариями оболочки, читающего ваш код. Мой любимый способ - снова отказаться от одинарных кавычек до двойных кавычек только для расширения переменной и сразу вернуться к одинарным кавычкам:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt
0
27.01.2020, 19:56

Теги

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