Ich arbeite an einem Skript, um meinen Download-Ordner nach dem Erstellungsdatum der Dateien zu sortieren. Dies ist das Skript, das ich verwende:
#!/bin/bash
cd ~/Downloads
for FILENAME in *
do
if [[ -f $FILENAME ]]; then
date="$(ls -l $FILENAME | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.')"
mkdir -vp "$date"
find . -maxdepth 1 -type f -name $FILENAME -exec mv {} "$date" \;
fi
done
cd -
Der Name des von diesem Skript erstellten Ordners ist einfach, Jun
was mich glauben lässt, dass irgendwo eine Art Konvertierung stattfindet.
Wenn ich nur ein
ls -l test0 | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.'
das Datum wird 19062014
korrekt angezeigt.
Dies ist das Ergebnis bash -x
des Skripts:
sigurd@Goliath ~ -> bash -x clean
+ cd /home/sigurd/Downloads
+ for FILENAME in '*'
+ [[ -f test0 ]]
++ ls -l test0
++ tr -s ' '
++ cut -d ' ' -f 6
++ tr -d .
+ date=Jun
+ mkdir -vp Jun
mkdir: created directory 'Jun'
+ find . -maxdepth 1 -type f -name test0 -exec mv '{}' Jun ';'
+ for FILENAME in '*'
+ [[ -f test1 ]]
++ ls -l test1
++ tr -s ' '
++ cut -d ' ' -f 6
++ tr -d .
+ date=Jun
+ mkdir -vp Jun
+ find . -maxdepth 1 -type f -name test1 -exec mv '{}' Jun ';'
+ cd -
/home/sigurd
Die von mir gesuchte Funktionalität besteht darin, dass das Skript Dateien in Ordner mit den Namen usw. verschieben soll 19_06_2014
, 20_06_2014
basierend auf dem Zeitpunkt der Dateierstellung.
Antwort1
Ich würde vorschlagen, ein Datumsformat wie zu verwenden 2014-06-19
. Auf diese Weise ls
werden sie in chronologischer Reihenfolge angezeigt.
Auf einem GNU-System:
#! /bin/bash -
cd ~/Downloads &&
find . -maxdepth 1 -type f -printf '%p\0%TF\0' |
while IFS= read -rd '' file && read -d '' date; do
mkdir -vp "$date" && mv "$file" "$date"
done
Mit zsh
auf jedem System:
#! /bin/zsh -
zmodload zsh/stat || exit
cd ~/Downloads &&
for file (./*(ND.)) {
zstat -A date -F %F +mtime $file &&
mkdir -p $date &&
mv $file $date
}
Antwort2
Wilde Vermutung: Sie haben einen Alias, ls
der verwendet wird, wenn Sie den Befehl interaktiv ausführen, und dieser Alias wird im Skript nicht verwendet. So etwas wie das hier vielleicht?
alias ls="ls --full-time"
Beachten Sie, dass es allgemein bekannt ist, dass der Versuch einer Analyse ls
keine gute Idee ist. Angenommen, Sie verwenden einen Linux-Rechner, wäre so etwas möglicherweise vorzuziehen:
stat "$FILENAME" | awk '/^Modify: /{print $2}'
EDIT: Oder, wie Stéphane weiter unten anmerkt, ist die Verwendung find
von with -printf
sogar noch besser. Die Ausgabe von stat
ist etwas einfacher vorherzusagen als die von ls
, ermöglicht aber -printf
ein Ausgabeformat, das vollständig von Ihnen kontrolliert wird.
Antwort3
Hier ist der komplette Code
#!/bin/bash
cd ~/Downloads
for FILENAME in $(find . -maxdepth 1 -type f); do
DATE=$(stat "$FILENAME" | awk '/^Modify: /{print $2}')
[ ! -d "$DATE" ] && mkdir -vp "$DATE"
mv "$FILENAME" "${DATE}/$FILENAME"
done
cd -