2016-07-22 3 views
0

Ich bin neu bei Unix und hatte unter Anforderung, um meine Aufgabe zu beenden.Suche eine Zeichenfolge in einer Datei, die auch in einer anderen Datei in Unix

Ich habe file1.dat, die Daten wie unten gezeigt hat.

case1.txt 
case2.txt 
case3.txt 
case4.txt 
case5.txt 

file1.dat hat nur Dateinamen

I Ordner haben, die in file1.dat

./all_files 
case1.txt 
case2.txt 
case3.txt 
case4.txt 

Daten in case1.txt, case2.txt, case3.txt oben genannten Dateien hat : Jetzt

step1 
step2 
step3 
step4 

, ich habe besonderen Schritt zu wagen sagt aus jeder Datei Schritt 2, das auch in file1.dat vorliegt

Hinweis: step2 ist nicht line no: 2 immer.

Antwort

0

Try this:

while read f; do 
    [ -f "$f" ] && sed -n '/step2/p' "$f" 
done < file1.dat 

gibt er die Linie (e) entsprechen step2 in jeder Datei in file.dat aufgeführt.

+0

vielen Dank .. – user180946

+0

Aber die Ausgabe hat auch die nicht übereinstimmenden Dateien angezeigt ... error: 'sed: Datei case5.txt kann nicht geöffnet werden, case5.txt ist in file1.dat vorhanden, aber nicht im Ordner ./all_files. Bitte helfen Sie – user180946

+0

Ich aktualisiert, um zu überprüfen, ob die Datei vorhanden ist, bevor Sie den Befehl sed anwenden. – SLePort

0
while read f; do 
    test -f "$f" && grep -F 'step2' "$f" 
done <file1.dat 

Die Linien file1.dat (enthaltend Dateinamen) werden nacheinander in die f Variable gelesen.

Der Körper der while -loop Tests die Datei vorhanden ist, um sicherzustellen, $f vor grep mit für den Textstring step2 in der angegebenen Datei zu suchen.

Eine etwas ausführlichere (aber gleichwertig) Version der Schleife:

while read f; do 
    if [ -f "$f" ]; then 
     grep -F 'step2' "$f" 
    fi 
done <file1.dat 

Je nachdem, wo Sie dies ausführen, können Sie leicht den grep Befehl ändern müssen. Wenn Sie diese in den Ordnern direkt über den Unterordner mit allen Dateien, zum Beispiel laufen:

grep -F 'step2' "all_files/$f" 

Es war nicht ganz klar, in der Frage, aber leicht einstellbar, wenn es sein muss.

Natürlich könnte man umgehen nur die file1.dat zusammen und sagen

grep -F 'step2' all_files/case?.txt 

ohne überhaupt Looping.

bearbeiten: mit neuen Anforderungen:

find ./all_files -type f -name "case?.txt" -print0 | 
xargs -0 grep -l -F 'step2' 

Dies wird durch alle Ordner unter dem all_files Ordner rekursiv, finden Sie die Dateien case?.txt passende und berichten, welche davon die gewünschte Zeichenfolge enthält.

Sie können das Muster strikter ändern, vielleicht zu etwas wie case[1-5].txt.

+0

danke .. könntest du bitte helfen, wenn der Befehl auch rekursiv funktioniert .. Unterordner in ./all_files/ und in der Anzeige der Dateiname auch 'case1.txt: step2',' case2.txt: step2' – user180946

+0

Das ändert die Lösung komplett, aber ok, ich füge es meiner Antwort hinzu. – Kusalananda

+0

danke .. aber wenn ich den Befehl ausgeführt habe, habe ich Fehler ausgegeben. '#find ./all_files -type f -name" * .txt "-print0 | xargs -0 grep -l -F 'step2'' 'finden: schlechte Option -print0' ' finden: [-H | -L] Pfad-Liste Prädikat-Liste' 'xargs: illegale Option - 0' ' xargs: Verwendung: xargs: [-t] [-p] [-e [eofstr]] [-E eofstr] [- I replstr] [-i [replstr]] [-L #] [-l [#]] [-n # [-x]] [-s Größe] [cmd [Argument ...]] ' – user180946

0

Wenn Sie step 2 aus jeder Datei im Verzeichnis ./all_files übernehmen möchten, wird files.dat nicht benötigt, es sei denn, Sie müssen es als Übung verwenden. Wenn Ihre Shell unterstützt Klammer Expansion:

grep "step2" all_files/case{1,5}.txt 

oder files.dat verwenden Sie in das Verzeichnis all_files ändern könnte und den Inhalt als Eingabe in grep umleiten:

cd all_files 
grep "step2" $(<../files.dat)