aprendendo scripts bash e estou tentando filtrar resultados com um grep aninhado em um loop for:
sample filenames:
this-file_AAC.txt
this-other_file_AAAC.txt
yep-a-file_AAC.nfo
oops_another_one.reamde
e este é o roteiro:
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
a ideia é que qualquer arquivo que contenha _AAC
terá operações aplicadas a ele; neste caso específico, basta imprimir em stdout para confirmar que os resultados estão corretos.
O problema é: nada passa da if
afirmação. então estou sentindo falta de não sei o quê. tudo o que funciona é a printf "input...
linha.
o que estou perdendo?
Responder1
Se você quiser corresponder todos os arquivos nomeados como .../something_AACxyz
, _AAC
na última parte do nome do arquivo, basta adicionar a _AAC
parte diretamente ao padrão glob/curinga:
for file in ./**/*_AAC*.{txt,reamde,nfo}; do
Se você quiser nomes de arquivos que _AAC
possam aparecer em qualquer parte, você pode fazer (no Bash):
for file in ./**/*.{txt,reamde,nfo}; do
if [[ $file == *_AAC* ]]; then
echo "'$file' contains _AAC"
else
echo "'$file' has NO _AAC"
fi
done
Aqui, você também obtém os arquivos que correspondem aos globs, mas não possuem a extensão _AAC
.
De qualquer forma, no Bash, você também pode ativar extglob
e reescrever o padrão em @(...|...)
vez da expansão de chaves:
for file in ./**/*_AAC*.@(txt|reamde|nfo); do
A expansão da chave produz vários globos distintos, enquanto @(..)
é apenas um único globo. (ou seja, *.{foo,bar}
é o mesmo que *.foo *.bar
) Com nullglob
set os não correspondentes não importam, mas se você tivesse failglob
definido, apenas um não correspondente seria suficiente para falhar em todo o comando.
Responder2
Onde seu script diz:
if grep -qF _AAC $file; then
está dizendo, "se o conteúdo do arquivo nomeado $file
contiver a string literal, _AAC
então ...." execute o conteúdo do then
bloco.
Se o que você quer dizer é procurar _AAC
na string resultante da expansão da variável $file
(ou seja, para verificar se _AAC aparece no próprio nome do arquivo), então em bash
, você precisa escrever:
if grep -qF _AAC <<< "$file"; then
Ou, como aponta @roaima, a string literal que você está procurando pode ser incluída na especificação do arquivo curinga.