Изучаю скриптинг 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 несовпадающие глобусы не имеют значения, но если бы вы использовали failglob
set, то даже одного несовпадающего глобуса было бы достаточно, чтобы вся команда завершилась неудачей.
решение2
Где в вашем сценарии говорится:
if grep -qF _AAC $file; then
он говорит: «если содержимое указанного файла $file
содержит литеральную строку, _AAC
то...» выполнить содержимое блока then
.
Если вы имеете в виду поиск _AAC
в строке, полученной в результате расширения переменной $file
(т. е. проверку того, появляется ли _AAC в самом имени файла), то в bash
, вам нужно написать:
if grep -qF _AAC <<< "$file"; then
Или, как указывает @roaima, искомая вами строка может быть включена в спецификацию файла подстановочных знаков.