Umleiten von geloopten Grep-Befehlen in separate Dateien

Umleiten von geloopten Grep-Befehlen in separate Dateien

Ich möchte mit grep ein Verzeichnis rekursiv durchsuchen, indem ich in einer Datei aufgelistete Muster verwende, und dann jedes Ergebnis zur späteren Bezugnahme in einer eigenen Datei speichern.

Ich habe einen Versuch gemacht (mitdiese Frageals Leitfaden) und kam zu folgendem Ergebnis:

#!/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."

Wenn ich es jedoch ausführe, bleibt die Konsole hängen, bis ich STRG-C drücke:

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

Wo liegt das Problem mit diesem Skript? Oder gehe ich falsch vor?

Antwort1

Hier gibt es einige Probleme:

  1. Die whileSchleife liest keine Eingabe. Das richtige Format ist

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

    Oder

    some other command | while read ...
    

    Ihre Schleife hängt daher und wartet auf Eingaben. Sie können dies testen, indem Sie Ihr Skript ausführen, dann etwas eingeben und die Eingabetaste drücken (hier habe ich eingegeben foo):

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

    Sie können dies verbessern, indem Sie Ihrem Folgendes eine Eingabeaufforderung hinzufügen read:

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

    Dies wird jedoch weiterhin ausgeführt, bis Sie es mit Ctrl+ stoppen C.

  2. Das || [[ -n "$line" ]](was bedeutet „ODER die Variable $line ist nicht leer“) wird nie ausgeführt. Da es hängt, wird das „ODER“ nie erreicht. Ich verstehe sowieso nicht, was Sie damit machen wollten. Wenn Sie nach „wenn definiert“ suchen und „wenn nicht“ verwenden readmöchten , benötigen Sie etwas wie:$line$lineread

    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
    

    Wenn hier $linenicht definiert ist, müssen Sie es trotzdem manuell eingeben. Ein saubererer Ansatz wäre, entweder eine Datei in die whileSchleife einzuspeisen:

    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
    

verwandte Informationen