grep не работает с именем файла из цикла for

grep не работает с именем файла из цикла for

Изучаю скриптинг bash и пытаюсь отфильтровать результаты с помощью вложенного grep в цикле for:

sample filenames:
  this-file_AAC.txt
  this-other_file_AAAC.txt
  yep-a-file_AAC.nfo
  oops_another_one.reamde

и вот сценарий:

shopt -s globstar nullglob dotglob
for file in ./**/*.{txt,reamde,nfo}; do
  printf "input: ${file}\n"
  if grep -qF _AAC $file; then
    printf "output: ${file}\n"
    # do stuff with $file
  fi
done

Идея заключается в том, что _AACк любому файлу, содержащему , будут применены операции; в этом конкретном случае просто выведите на стандартный вывод, чтобы подтвердить правильность результатов.

проблема в том, что дальше утверждения ничего не проходит if. так что я пропускаю «я не знаю что». все, что работает — это строка printf "input....

что я упускаю?

решение1

Если вы хотите найти все файлы, имена которых имеют вид .../something_AACxyz, с _AACпоследней частью имени файла, просто добавьте эту _AACчасть непосредственно в шаблон/подстановочный знак глобуса:

for file in ./**/*_AAC*.{txt,reamde,nfo}; do

Если вам нужны имена файлов, которые _AACмогут появляться в любой части, вы можете сделать следующее (в Bash):

for file in ./**/*.{txt,reamde,nfo}; do
    if [[ $file == *_AAC* ]]; then
         echo "'$file' contains _AAC"
    else
         echo "'$file' has NO _AAC"
    fi
done

Здесь вы также получите файлы, соответствующие шаблонам, но не имеющие расширения _AAC.


В любом случае, в Bash вы также можете включить extglobи переписать шаблон @(...|...)вместо расширения фигурных скобок:

for file in ./**/*_AAC*.@(txt|reamde|nfo); do

Расширение скобок создает несколько различных глобусов, тогда как с помощью @(..)это всего лишь один глобус. (т.е. *.{foo,bar}то же самое, что и *.foo *.bar). При nullglobиспользовании set несовпадающие глобусы не имеют значения, но если бы вы использовали failglobset, то даже одного несовпадающего глобуса было бы достаточно, чтобы вся команда завершилась неудачей.

решение2

Где в вашем сценарии говорится:

  if grep -qF _AAC $file; then

он говорит: «если содержимое указанного файла $fileсодержит литеральную строку, _AACто...» выполнить содержимое блока then.

Если вы имеете в виду поиск _AACв строке, полученной в результате расширения переменной $file(т. е. проверку того, появляется ли _AAC в самом имени файла), то в bash, вам нужно написать:

  if grep -qF _AAC <<< "$file"; then

Или, как указывает @roaima, искомая вами строка может быть включена в спецификацию файла подстановочных знаков.

Связанный контент