#bash
Вопрос:
Я читаю некоторые конфигурации из текстового файла и сохраняю их в переменной. Они разделены трубой вот так:
a,b|c,d|e,f|g,h
Я хочу передать их в команду sed, чтобы заменить левое значение на правое значение в текстовом файле и вывести его в другой файл.
У меня есть:
#!/bin/bash
test="a,b|c,d|e,f|j,l"
arr=(`echo $test | sed 's/|/n/g'`)
sub=""
for i in "${arr[@]}"
do
echo "$i"
array=(`echo $i | sed 's/,/n/g'`)
sub ="s/${array[0]}/${array[1]}/g; "
done
sed $sub ${FILE} > output.json
Когда я это делаю, он запускает команду sed для каждого элемента в arr. Итак, после первого sed в нем говорится:
No such file or directory
Теперь, если я не передам $sub в качестве переменной, а просто помещу в нее всю строку, выполните это в одной команде sed, и это сработает:
sed "s/a/b/g; s/c/d/g; s/e/f/g; s/g/h/g;" ${FILE} > output.json
Как я могу передать свои сопоставители в качестве переменной, как в моем первом примере, но заставить ее выполнять все это в одной команде sed, как во втором примере?
Комментарии:
1.
var='a,b|c,d|e,f|g,h'; var="${var//,//}"; var="${var//|//g; s/}"; sed "s/${var}/g" "$file"
2. С вашим сценарием много проблем — проверьте свои сценарии с помощью shellcheck.net
Ответ №1:
Как я могу передать свои сопоставители в качестве переменной, как в моем первом примере, но заставить ее выполнять все это в одной команде sed, как во втором примере?
Шеллчек подскажет вам:
Line 12:
sed $sub ${FILE} > output.json
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
sed "$sub" "${FILE}" > output.json
Потому что после ;
разбиения шаблона на слова остается пробел. Процитируйте его, чтобы предотвратить расширение. Если $sub
не указано в кавычках, файл s/c/d/g;
анализируется как имя файла, поэтому sed
завершается без такого файла или каталога.