wie verwende ich grep und mv zusammen in einem Verzeichnis in der Shell?

wie verwende ich grep und mv zusammen in einem Verzeichnis in der Shell?

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 ffindet 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 -qSchalter macht grep "ruhig", d.h. es gibt nichts aus. Die -execAnweisung ist wahr, wenngrepist erfolgreich, d. h., es findet die Zeichenfolge.

  • -exec mv -i {} DEST \;verschiebt eine Datei mit der ZeichenfolgePRÜFENin das VerzeichnisZIEL.

    Der -iSchalter 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 skipAktion für gefundene Verzeichnisse unter den Eingabeargumenten.

    Dies ist nicht wirklich erforderlich; es vermeidet lediglich die Benachrichtigung grep: SOURCE/DIR: Is a directorybeim Auffinden von Verzeichnissen. Wenn Sie rekursives Lesen von Dateien in Verzeichnissen wünschen, verwenden Sie die Aktion recurseoder noch kürzer einfach den entsprechenden -rSchalter (siehe auch Punkt unten).

  • SOURCE/*

    stimmt mit allen Dateien im Verzeichnis überein, SOURCEindem die Shell verwendet wirdGlotzen. Versteckte Dateien werden standardmäßig nicht abgeglichen; dies kann durch eine entsprechende Einstellung shopt -s dotglobin der Bash geändert werden, bevor der grepBefehl 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 SOURCEohne 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, echoum zu sehen, welche Befehle ausgeführt werden sollen, d. h. mvzu 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.

verwandte Informationen