Wie durchsuchen Sie den Inhalt aller Dateien in einem Verzeichnis nach „TEST“ und verschieben diese Dateien dann in ein anderes Verzeichnis (z. B. das Home-Verzeichnis)?
Antwort1
Sie können kombinierengrepUndfindenfür diese Aufgabe:
find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;
Wie es funktioniert
find SOURCE -maxdepth 1 -type f
findet alle Dateien (-type f
) im VerzeichnisQUELLE.Wenn Sie auch Dateien in Unterverzeichnissen einschließen möchten, entfernen Sie einfach
-maxdepth 1
.-exec grep -q TEST {} \;
grepst die Dateien einzeln nach der ZeichenfolgePRÜFEN. Hier{}
ist die Datei, die gerade verarbeitet wird.Der
-q
Schalter macht grep "ruhig", d.h. es gibt nichts aus. Die-exec
Anweisung ist wahr, wenngrepist erfolgreich, d. h., es findet die Zeichenfolge.-exec mv -i {} DEST \;
verschiebt eine Datei mit der ZeichenfolgePRÜFENin das VerzeichnisZIEL.Der
-i
Schalter machtmv„interaktiv“, d. h., es erfolgt eine Abfrage, bevor andere Dateien überschrieben werden.
Antwort2
Nur eine weitere Alternative (dies erfordert allerdings einige GNU-spezifische Erweiterungen; da Sie die Frage mit „Unix“ markiert haben, passt sie möglicherweise nicht zu Ihnen):
grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
grep -l
druckt übereinstimmende Dateinamen anstelle der normalen Ausgabe.
grep -Z
gibt eine durch Nullbytes getrennte Ausgabe aus, was beim Umgang mit ungewöhnlichen Dateinamen über Pipes eine sichere Sache ist.
grep -d skip
definiert die
skip
Aktion für gefundene Verzeichnisse unter den Eingabeargumenten.Dies ist nicht wirklich erforderlich; es vermeidet lediglich die Benachrichtigung
grep: SOURCE/DIR: Is a directory
beim Auffinden von Verzeichnissen. Wenn Sie rekursives Lesen von Dateien in Verzeichnissen wünschen, verwenden Sie die Aktionrecurse
oder noch kürzer einfach den entsprechenden-r
Schalter (siehe auch Punkt unten).SOURCE/*
stimmt mit allen Dateien im Verzeichnis überein,
SOURCE
indem die Shell verwendet wirdGlotzen. Versteckte Dateien werden standardmäßig nicht abgeglichen; dies kann durch eine entsprechende Einstellungshopt -s dotglob
in der Bash geändert werden, bevor dergrep
Befehl ausgegeben wird.Man könnte versucht sein, einfach
SOURCE/.*
die Eingabeargumente zu ergänzen, aber das hat möglicherweise unerwartete Konsequenzen, wenn es zusammen mit verwendet wird-r
(da wir auch.
und zuordnen..
).Wenn eine rekursive Übereinstimmung gewünscht wird, verwenden Sie einfach „
-r SOURCE
ohne Datei-Globbing“ als Eingabeargument, wodurch versteckte Dateien in die Verzeichnisstruktur einbezogen werden.xargs -0
interpretiert die Eingabe als durch Null getrennt.
xargs -I{}
definiert
{}
als Platzhalter für das Eingabeargument.mv -i
macht den Zug gemäß Dennis‘ Vorschlag interaktiv, um Fehler zu vermeiden.
Um dieses Muster (oder Befehle im Allgemeinen) zu testen, besteht eine nützliche Technik darin, vor dem eigentlichen Befehl einzufügen, echo
um zu sehen, welche Befehle ausgeführt werden sollen, d. h. mv
zu zu wechseln echo mv
.
Antwort3
$ mv TEST* /Pfad/zum/Ziel
Funktioniert bei mir, hoffe, es funktioniert bei Ihnen. In meinem Fall war es:
$ mv note_[5,6]* ~/Dokumente/Notizen
Dadurch wurden note_5_math.pdf und note_6_math.pdf in das Verzeichnis home/documents/notes verschoben.