Redirigir comandos grep en bucle a archivos separados

Redirigir comandos grep en bucle a archivos separados

Me gustaría usar grep para buscar recursivamente en un directorio, usando patrones enumerados en un archivo, y luego almacenar cada resultado en su propio archivo para consultarlo más adelante.

Hice un intento (usandoesta preguntacomo guía) y se le ocurrió:

#!/bin/bash

mkdir -p grep_results   # For storing results

echo "Performing grep searches.."
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Seaching for $line.."
    grep -r "$line" --exclude-dir=grep_results . > ./grep_results/"$line"_infile.txt
done

echo "Done."

Sin embargo, cuando lo ejecuto, la consola se bloquea hasta que presiono CTRL-C:

$ bash grep_search.sh search_terms.txt
Performing grep searches..

¿Dónde está el problema con este script? ¿O me estoy acercando a esto mal?

Respuesta1

Hay algunos problemas aquí:

  1. El whilebucle no lee ninguna entrada. El formato correcto es

    while read line; do ... ; done < input file
    

    O

    some other command | while read ...
    

    Por lo tanto, su bucle está colgado, esperando entrada. Puedes probar esto ejecutando tu script y luego escribiendo cualquier cosa y presionando Enter (aquí ingresé foo):

    $ foo.sh 
    Performing grep searches..
    foo
    Searching for foo..
    

    Puede mejorar esto agregando un mensaje a su read:

    while IFS='' read -p "Enter a search pattern: " -r line ...
    

    Sin embargo , seguirá ejecutándose hasta que lo detengas con Ctrl+ C.

  2. ( que || [[ -n "$line" ]]significa "O la variable $line no está vacía") nunca se ejecuta. Desde que readse bloquea, nunca se alcanza el "OR". De todos modos, no entiendo qué querías que hiciera. Si desea buscar $linesi $lineestá definido y usarlo readsi no lo está, necesitará algo como:

    if [[ -n "$line" ]]; then
         grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
    else
        while IFS='' read -p "Enter a search pattern: " -r line || [[ -n "$line" ]]; do
          grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
        done
    fi
    

    Aquí, si $lineno está definido, aún deberá ingresarlo manualmente. Un enfoque más limpio sería alimentar un archivo al whilebucle:

    while IFS='' read -r line || [[ -n "$line" ]]; do
      grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
    done < list_of_patterns.txt
    

información relacionada