множественный ввод grep

Фрагмент вопроса:

IFS=$'\n' a=($str)

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

IFS=$'\n'; a=($str)

или

IFS=$'\n'
a=($str)

Это объясняет, почему глобальный IFSбыл изменен, и почему слово -разбиение $strна элементы массива было выполнено с использованием нового значения IFS.

У вас может возникнуть соблазн использовать подоболочку, чтобы ограничить эффект IFSмодификации, подобной этой:

str="value 0:value 1"
a=( old values )
( # Following code runs in a subshell
 IFS=":"
 a=($str)
 printf 'Subshell IFS: %q\n' "${IFS}"
 echo "Subshell: a[0]='${a[0]}' a[1]='${a[1]}'"
)
printf 'Parent IFS: %q\n' "${IFS}"
echo "Parent: a[0]='${a[0]}' a[1]='${a[1]}'"

, но вы быстро заметите, что модификация aтакже ограничена подоболочкой :

.

Subshell IFS: :
Subshell: a[0]='value 0' a[1]='value 1'
Parent IFS: $' \t\n'
Parent: a[0]='old' a[1]='values'

Затем у вас может возникнуть соблазн сохранить/восстановить IFS, используя решение из этого предыдущего ответа от @msw или попробовать использовать local IFSвнутри функции , как было предложено от @helpermethod. Но довольно скоро вы замечаете, что у вас возникают всевозможные проблемы, особенно если вы являетесь автором библиотеки, которому необходимо быть устойчивым к неправильному вызову скриптов :

.

  • Что делать, если IFSизначально не было установлено?
  • Что если мы работаем сset -u(a.k.aset -o nounset)?
  • Что, если IFSчитается -только через declare -r IFS?
  • Что делать, если мне нужен механизм сохранения/восстановления для работы с рекурсией и/или асинхронным выполнением (, например trapобработчик `)?

Не сохраняйте и не восстанавливайте IFS. Вместо,придерживаться временных модификаций:

  • Чтобы ограничить изменение переменной одной командой, встроенной -или вызовом функции, используйте IFS="value" command.

    • Чтобы прочитать несколько переменных путем разделения по определенному символу (:, используемому ниже в качестве примера ), используйте:

      IFS=":" read -r var1 var2 <<< "$str"
      
    • Для чтения массива используйте (вместоarray_var=( $str )):

      IFS=":" read -r -a array_var <<< "$str"
      
  • Ограничьте последствия изменения переменной подоболочкой.

    • Для вывода элементов массива через запятую:

      (IFS=","; echo "${array[*]}")
      
    • Чтобы записать это в строку:

      csv="$(IFS=","; echo "${array[*]}")"
      

0
25.08.2020, 19:08
1 ответ
 find path -type f -iname "*.gz" -exec zgrep  "word" {} \; >>result

Проверено, работает нормально

0
18.03.2021, 23:10

Теги

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