Grep-Befehl, um Dateien zu finden, die Textzeichenfolgen enthalten, und sie zu verschieben

15

Mit dem folgenden Befehl kann ich Dateien in einem Ordner suchen, der eine bestimmte Textzeichenfolge enthält:

grep -lir 'string' ~/directory/*

Wie verschiebe ich die Dateien, die im obigen Ergebnis erscheinen, an einen anderen Ort?

Spartanblogger
quelle
Hier ist es. grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Alan Dong

Antworten:

10

Hüten Sie sich wie immer vor grep -r. -rDies ist keine Standardoption, und in einigen Implementierungen, wie allen anderen als den neuesten GNU-Versionen grep, folgen sie symbolischen Links, wenn Sie den Verzeichnisbaum absteigen. Dies ist im Allgemeinen nicht das, was Sie wollen, und kann schwerwiegende Folgen haben, wenn zum Beispiel ein Symlink zu "/ "irgendwo im Verzeichnisbaum.

In der Unix-Philosophie verwenden Sie einen Befehl, um Verzeichnisse nach Dateien zu durchsuchen, und einen anderen, um den Inhalt zu überprüfen.

Mit GNU-Tools würde ich Folgendes tun:

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

Aber achten Sie auch dann auf die Rennbedingungen und mögliche Sicherheitsprobleme, wenn Sie es als ein Benutzer in einem Verzeichnis ausführen, das von einem anderen Benutzer beschrieben werden kann.

Stéphane Chazelas
quelle
das gibt mir fehler find: `grep 'wird durch signal 13 beendet. irgendwelche ahnung was läuft falsch?
Reena Parekh
@ReenaParekh, das wäre ein SIGPIPE. Dies würde nur passieren, wenn das xargsProgramm vor dem Lesen bis zum Ende der arg-Datei beendet wird. Dies sollte nur geschehen, wenn xargs selbst getötet wird oder aus irgendeinem Grund fehlschlägt. In diesem Fall würde ich erwarten, dass Sie auch einen Fehler sehen.
Stéphane Chazelas
15

Verwendung xargsin Verbindung mit mvder dritten Syntax von:mv [OPTION]... -t DIRECTORY SOURCE...

grep -lir 'string' ~/directory/* | xargs mv -t DEST

Seien Sie vorsichtig mit Dateien, die Sonderzeichen (Leerzeichen, Anführungszeichen) enthalten. In diesem Fall kann das Filtern der Liste mit sed(Hinzufügen von Anführungszeichen um Dateinamen mit s/^/'/;s/$/'/) hilfreich sein. Sie müssen jedoch sicherstellen, dass diese Anführungszeichen nicht in den Dateinamen enthalten sind. GNU grephat die Option -Z/ --null, Dateinamen mit NUL zu beenden.

Eine Alternative zur dritten Syntax für mvist die Verwendung xargsmit dem Platzhalter string ( -I).

Eine andere Option ist die Befehlsersetzung - $( )oder Backticks ``(in Bash), wie in der Antwort von ire_and_curses erwähnt.

peterph
quelle
3
gnu grep unterstützt ein -Z-Flag, um Dateinamen durch das Null-Byte-Zeichen zu trennen. In Verbindung mit dem -0-Flag für xargs können Sonderzeichen
umgangen werden, die
@ChandraRavoori danke, ich habe die Antwort aktualisiert.
Peterph
7

Wenn Ihre Dateinamen keine Sonderzeichen (Leerzeichen oder \[*?) enthalten, verwenden Sie die Befehlssubstitution :

mv `grep -lir 'string' ~/directory/*` destination/
ire_and_curses
quelle
Backticks sind veraltet. Verwenden Sie stattdessen das portablere, lesbarere und stapelbarere $ (...).
Benutzer unbekannt
1

Verwenden Sie nur die von POSIX angegebenen Funktionen und machen Sie keine Annahmen zu Dateinamen:

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

Anmerkungen:

Sie sagten "Zeichenfolge" nicht "Muster", daher scheint die -FOption (feste Zeichenfolgensuche) grepangemessen.

Befindet sich Ihr Zielverzeichnis irgendwo in Ihrem Suchverzeichnis, kann es zu unangenehmen Rennbedingungen kommen.

POSIX-Spezifikationen für grep

POSIX-Spezifikationen für find

Platzhalter
quelle
Dies könnte die beste Lösung für Macos / BSD sein
Ali
0

Mit GNU parallel :

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dong für seine ursprüngliche antwort mit xargs.

Zach
quelle
Wäre nett gewesen, wenn du @ lindongs Antwort in den Kommentaren von vor über einem Jahr gutgeschrieben hättest.
Roaima
0

-Angenommen, Sie haben das Zielverzeichnis als 'extern' und müssen alle XLS-Dateien verschieben, können Sie den folgenden Befehl versuchen

sudo mv find /var/log/ -type f -name "*.xls"/ external /

SURESH BABU
quelle