Как использовать переменные в команде sed

# #linux #sed #gitlab-pipelines

#удар #ракушка #сед

Вопрос:

У меня есть файл под названием «text_file1.txt» и содержимое файла «тема= /C=US/O=AAA/OU=QA/OU=12345/OU=TESTAPP/»

Теперь я хочу добиться того, чтобы контент был таким, как показано ниже: «тема= /C=US/O=AAA/$$$QA/###12345/@@@TESTAPP/»

когда я выполняю приведенный ниже фрагмент кода:

 #! /bin/ksh OU1="QA" OU2=12345 OU3="TESTAPP" `sed -i "s/OU=$OU1/$${OU1}/g" text_file1.txt` `sed -i "s/OU=$OU2/###${OU2}/g" text_file1.txt` `sed -i "s/OU=$OU3/@@@${OU3}/g" text_file1.txt` content=`cat text_file1.txt` echo "content:$content"  

я получаю такой результат:

 content:subject= /C=US/O=Wells Fargo/2865528655{OU1}/###12345/@@@TESTAPP/CN=03032015_CUST_2131_Unix_CLBLABB34C02.wellsfargo.com  

только эта команда « sed -i "s/OU=$OU1/$$$${OU1}/g" text_file1.txt » работает не так, как ожидалось.Кто-нибудь может, пожалуйста, предложить какую-нибудь идею по этому поводу?

Заранее спасибо.

Комментарии:

1. вы также можете оптимизировать, написав только 1 sed и разделив каждый s/// с помощью a ; после применения решения @AvinashRaj для вашего $ и обратного tik

Ответ №1:

В это играют две вещи:

  1. Вы должны экранировать $ (т. е. Использовать $ ) строки оболочки в двойных кавычках , если вам нужен литерал $ , и
  2. не сохраняет своего буквального значения, когда оно появляется перед $ внутренней обратной связью (то есть, внутренняя обратная связь $ становится справедливой $ ).

Когда вы пишете

 `sed -i "s/OU=$OU1/$${OU1}/g" text_file1.txt`  

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

 sed -i "s/OU=$OU1/$${OU1}/g" text_file1.txt  

Поскольку $$$$ находится внутри строки в двойных кавычках, происходит расширение переменной, и она расширяется как два вхождения $$ (идентификатор процесса оболочки, выполняющей расширение). Это означает, что код sed видит, что в конечном счете

 s/OU=QA/1234512345{OU1}/g  

…если идентификатор процесса порожденной подоболочки равен 12345 .

В данном конкретном случае вам не нужна подстановка команд (обратные ссылки), поэтому вы можете написать

 sed -i "s/OU=$OU1/$${OU1}/g" text_file1.txt  

Однако использование переменных оболочки в коде sed всегда является проблемой. Подумайте, если хотите, что произошло бы, если OU1 бы имело значение /; e rm -Rf * # (подсказка: в GNU sed есть e инструкция, которая запускает команды оболочки). По этой причине я бы всегда предпочитал awk выполнять замены, связанные с переменными оболочки:

 cp text_file1.txt text_file1.txt~ awk -v OU1="$OU1" '{ gsub("OU=" OU1, "$$" OU1) } 1' text_file1.txt~ gt; text_file1.txt  

Это позволяет избежать проблем с внедрением кода, не рассматривая OU1 его как код.

Если у вас есть GNU awk 4.1 или более поздняя версия,

 awk -v OU1="$OU1" -i inplace '{ gsub("OU=" OU1, "$$" OU1) } 1' text_file1.txt  

может сделать все это без (видимого) временного файла.

Ответ №2:

Помогает ли это для начала?

 echo '' OU1="QA" echo "subject= /C=US/O=AAA/OU=${OU1}/OU=12345/OU=TESTAPP/"  | sed -e "s|/OU=${OU1}/|/OU=$${OU1}/|g"  

В результате получается:

тема= /C=США/O=AAA/OU=$$$QA/OU=12345/OU=ТЕСТОВОЕ ПРИЛОЖЕНИЕ/

(Вы путаете использование знаков$.)

Ответ №3:

Вы должны быть осторожны при вводе $ двойных кавычек.

 sed -i "s/OU=$OU1/"'$

Пример:

 $ OU1="QA" $ echo 'OU=QA' | sed "s/OU=$OU1/"'$



"${OU1}/g" text_file1.txt
Пример:


"${OU1}/g" $$QA

«${OU1}/g» text_file1.txt

Пример: