Зачем `читать строку; объявить $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-скриптах.

Другие вопросы по тегам