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_nameYYYYMMDD
wobei file_name der Name der Originaldatei ist und YYYYMMDD das heutige Datum in Jahr, Monat, Tag ist. Zum Beispiel film.mkv
geht 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-%d
Ausgabe: 2016-10-31
nü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 find
Befehl 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 mv
durch 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 sh
Anruf 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 sh
ganz 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
( mv
sofern unterstützt).