aprendiendo secuencias de comandos bash y estoy tratando de filtrar los resultados con un grep anidado en un bucle for:
sample filenames:
this-file_AAC.txt
this-other_file_AAAC.txt
yep-a-file_AAC.nfo
oops_another_one.reamde
y este es el guión:
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
la idea es que a cualquier archivo que contenga _AAC
se le aplicarán operaciones; en este caso específico, simplemente imprima en stdout para confirmar que los resultados son correctos.
El problema es: nada pasa de la if
declaración. así que me falta no-sé-qué. Todo lo que funciona es la printf "input...
línea.
¿Qué me estoy perdiendo?
Respuesta1
Si desea hacer coincidir todos los archivos con nombres como .../something_AACxyz
, _AAC
en la última parte del nombre de archivo, simplemente agregue la _AAC
parte directamente al patrón global/comodín:
for file in ./**/*_AAC*.{txt,reamde,nfo}; do
Si desea nombres de archivos que _AAC
puedan aparecer en cualquier parte, puede hacer (en Bash):
for file in ./**/*.{txt,reamde,nfo}; do
if [[ $file == *_AAC* ]]; then
echo "'$file' contains _AAC"
else
echo "'$file' has NO _AAC"
fi
done
Aquí también obtienes los archivos que coinciden con los globos, pero que no tienen _AAC
.
En cualquier caso, en Bash, también puedes habilitar extglob
y reescribir el patrón con @(...|...)
en lugar de la expansión de llaves:
for file in ./**/*_AAC*.@(txt|reamde|nfo); do
La expansión de llaves produce múltiples globos distintos, mientras que con @(..)
ella es solo un globo. (es decir, *.{foo,bar}
es lo mismo que *.foo *.bar
) Con nullglob
set, los que no coinciden no importan, pero si lo hubiera failglob
configurado, solo uno que no coincida sería suficiente para fallar todo el comando.
Respuesta2
Donde tu guión dice:
if grep -qF _AAC $file; then
está diciendo, "si el contenido del archivo nombrado $file
contiene la cadena literal _AAC
entonces ..." ejecute el contenido del then
bloque.
Si lo que quiere decir es buscar _AAC
en la cadena resultante de la expansión de la variable $file
(es decir, verificar si _AAC aparece en el nombre del archivo), entonces en bash
, debe escribir:
if grep -qF _AAC <<< "$file"; then
O, como señala @roaima, la cadena literal que está buscando se puede incluir en la especificación del archivo comodín.