grep no funciona con el nombre de archivo del bucle for

grep no funciona con el nombre de archivo del bucle for

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 _AACse 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 ifdeclaració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, _AACen la última parte del nombre de archivo, simplemente agregue la _AACparte directamente al patrón global/comodín:

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

Si desea nombres de archivos que _AACpuedan 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 extgloby 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 nullglobset, los que no coinciden no importan, pero si lo hubiera failglobconfigurado, 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 $filecontiene la cadena literal _AACentonces ..." ejecute el contenido del thenbloque.

Si lo que quiere decir es buscar _AACen 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.

información relacionada