Зачем `читать строку; объявить $line` и `найти... +`?
Приведенный ниже скрипт работает, но с какой целью declare $line
иметь? Если я уберу это, это не сработает.
И в чем разница {} \;
а также {} +
в find
команда?
awk '{print "old="$1" new="$2}' list.txt |\
while IFS= read line; do
declare $line
find /path -name '*.ext' -exec sed -i "s/\b$old\b/$new/" {} +
done
2 ответа
declare
устанавливает переменные: ваш awk
команда выдает содержимое формы old=foo new=bar
, Бег declare old=foo new=bar
устанавливает эти две переменные.
Тем не менее, это неправильный и неаккуратный способ сделать это. Вместо этого используйте read
для непосредственного чтения нужных полей из входного файла и назначения переменных (подробнее об этом в BashFAQ # 1):
while read -u 3 -r old new _; do
find /path -name '*.ext' -exec sed -i "s/\b$old\b/$new/" {} +
done 3<list.txt
Чтобы сделать это немного более безопасным, можно также избежать буквального содержимого, чтобы его не обрабатывали как регулярные выражения:
requote() { sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$1"; };
substquote() { sed 's/[&/\]/\\&/g' <<< "$1"; }
while read -u 3 -r old new _; do
find /path -name '*.ext' -exec \
sed -i "s/\b$(requote "$old")\b/$(substquote "$new")/" {} +
done 3<list.txt
Обратите внимание, что я не изменил использование \b
, расширение которого многие реализации sed
не поддержу Смотрите BashFAQ #21 для альтернативных подходов к выполнению подстановок буквенных строк.
Для полноты (хотя эту несвязанную тему действительно следовало бы задать в качестве отдельного вопроса - и в этом случае ее можно было бы закрыть как дубликат, как это уже было задано и получено ответом), разрешите цитату из find
справочная страница:
-exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca‐ tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.
Встроенные функции объявлений или наборов, которые являются точными синонимами, позволяют изменять свойства переменных. Это очень слабая форма набора текста, доступная в некоторых языках программирования. Команда Declare относится к версии 2 или более поздней версии Bash. Команда typeset также работает в Ksh-скриптах.