Verwenden von mv zum Wechseln in ein anderes Verzeichnis und sofortigen Umbenennen

Verwenden von mv zum Wechseln in ein anderes Verzeichnis und sofortigen Umbenennen

Ich möchte alle Dateien kennen, die größer als 100 MB sind und im letzten Monat nicht aufgerufen wurden. Ich habe erfolgreich Folgendes geschrieben:

find / -size +100M -atime +30

Und jetzt möchte ich diese Dateien in einen Ordner namens /big-not-used verschieben und den Namen wie folgt ändern: file_nameYYYYMMDDwobei file_name der Name der Originaldatei ist und YYYYMMDD das heutige Datum in Jahr, Monat, Tag ist. Zum Beispiel film.mkvgeht es zu/big-not-used/film.mkv20161031

Mein Satz wäre:

find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;

Aber ich weiß nicht, wie ich das heutige Datum an den Dateinamen anhängen kann. Ich habe festgestellt, dass die date +%Y-%m-%dAusgabe: 2016-10-31nützlich ist. Nun bleibt die Frage, wie ich den Namen dieser Datei bekomme. Folgendes: https://stackoverflow.com/questions/5456120/wie-man-nur-den-Dateinamen-mit-linux-find-erhält

... -exec basename {} \;

Vielleicht?:

find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

Es tritt jedoch ein Fehler auf, da basename mit dem vollständigen Pfad der Datei antwortet und nicht mit dem Namen, den ich verwenden würde:

${var##/*/}

um den Dateinamen zu erhalten, aber die Frage ist, wie ich die basename {}Antworten in die Variable im vorherigen Ausdruck einfüge!?.

Vielleicht?

$(${$(basename {})##/*/})

Es heißt jedoch, dass in der Nähe des unerwarteten „}“ ein syntaktischer Fehler vorliegt …

Antwort1

Sie waren nah dran mit:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

Aber ohne Anführungszeichen $(...)erfolgt die Shell-Erweiterung von Konstruktenbevor der findBefehl ausgeführt wirdMit anderen Worten, bei der obigen Befehlszeile wird tatsächlich Folgendes ausgeführt:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/{}2016-10-30 \;

Weil das Ergebnis $(basename {})einfach ist {}und Sie deshalb den vollständigen Pfadnamen erhalten. Versuchen Sie stattdessen Folgendes:

find / -size +100M -atime +30 \
  -exec sh -c 'mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

Zum Ausprobieren können Sie mvdurch ersetzen echo mv, wie folgt:

find / -size +100M -atime +30 \
  -exec sh -c 'echo mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

... und sehen Sie, wie die generierten Befehle aussehen.

Antwort2

Ich habe Larks Lösung ein wenig verbessert, um nur einen einzigen shAnruf zu tätigen:

find / -size +100M -atime +30 -exec sh -c \
  'for f do mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"; done' sh {} +

Alternativ shganz ohne Anrufe:

while IFS= read -r f; do
  mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)

(Letzteres unter der Annahme, dass die Dateinamen keine Zeilenumbrüche enthalten.)

Zum Debuggen möchten Sie möglicherweise etwas hinzufügen -v( mvsofern unterstützt).

verwandte Informationen