cabby79
Anmeldungsdatum: 11. August 2007
Beiträge: 239
|
Hallo zusammen, ich habe nachstehendes Skript: | #!/bin/bash
for file in * .* ; do
timestamp="$( stat -c %y \"$file\" | sed 's/-.. .*//; s:-:/:' )"
echo mkdir -p "./$timestamp"
echo mv -i -t "$timestamp" "$file"
done
|
getestet um Textdateien nach Änderungsdatum zu sortieren. Leider brachte dies nicht den erhofften Erfolg da tlw. Dateien von 2018 in 2017 landen. Auch bei den Monaten gibt es Durcheinander. Es gibt doch nur zwei Trigger bei .odt Dateien oder? Zugriffsdatum und Änderungsdatum oder? VG
cabby79
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
cabby79 schrieb:
| #!/bin/bash
for file in * .* ; do
timestamp="$( stat -c %y \"$file\" | sed 's/-.. .*//; s:-:/:' )"
echo mkdir -p "./$timestamp"
echo mv -i -t "$timestamp" "$file"
done
|
Das Quoting ist auf jeden Fall falsch. Und durch die beiden echo in Zeilen 5 und 6 wird natürlich nix verschoben.
getestet um Textdateien nach Änderungsdatum zu sortieren. Leider brachte dies nicht den erhofften Erfolg da tlw. Dateien von 2018 in 2017 landen. Auch bei den Monaten gibt es Durcheinander. Es gibt doch nur zwei Trigger bei .odt Dateien oder? Zugriffsdatum und Änderungsdatum oder?
Generell ist es immer gut, wenn Du auch das Ergebnis der Anwendung postest, damit man sehen kann, was schief geht. Also, was passiert?
|
dingsbums
Anmeldungsdatum: 13. November 2010
Beiträge: 3532
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | suchordner="/pfad/zum/suchordner"
zielordner="/pfad/zum/zielordner"
for datei in $(find "$suchordner" -type f);do
# datum im format jjjj-mm-tt
datum=$(stat -c %y "$datei" | awk '{print $1}')
# jahr im format jjjj
jahr=$(stat -c %y "$datei" | awk '{print $1}' | cut -d '-' -f1)
# jahresordner im zielordner anlegen
mkdir -p "$zielordner"/"$jahr"
# falls dateiname bereits existiert, hänge dateidatum an
if [ -f "$zielordner"/"$jahr"/"$(basename "$datei")" ];then
cp -v "$datei" "$zielordner"/"$jahr"/"$(basename "$datei")"."$datum"
else
cp -v "$datei" "$zielordner"/"$jahr"/"$(basename "$datei")"
fi
done
|
Bei Bedarf cp durch mv ersetzen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
dingsbums schrieb: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | suchordner="/pfad/zum/suchordner"
zielordner="/pfad/zum/zielordner"
for datei in $(find "$suchordner" -type f);do
# datum im format jjjj-mm-tt
datum=$(stat -c %y "$datei" | awk '{print $1}')
# jahr im format jjjj
jahr=$(stat -c %y "$datei" | awk '{print $1}' | cut -d '-' -f1)
# jahresordner im zielordner anlegen
mkdir -p "$zielordner"/"$jahr"
# falls dateiname bereits existiert, hänge dateidatum an
if [ -f "$zielordner"/"$jahr"/"$(basename "$datei")" ];then
cp -v "$datei" "$zielordner"/"$jahr"/"$(basename "$datei")"."$datum"
else
cp -v "$datei" "$zielordner"/"$jahr"/"$(basename "$datei")"
fi
done
|
Bei Bedarf cp durch mv ersetzen.
Solche Command Substitutions wie in Zeile 4 gehen schief, sobald Leerzeichen oder andere in den Dateinamen vorkommen. Robuster ist es, find mit "-exec" zu nutzen, um die gefundenen Dateinamen über die Kommandozeile an die Shell zu übergeben. Was auch gut funktioniert, ist find ... -print0 mit while IFS= read -rd '' (nur in der bash ) zu kombinieren. Du kannst es Dir etwas leichter mit dem Quoting machen, indem Du nicht mehrere gequotete Zeichenketten aneinander hängst, sondern das in einer erledigst, z.B. Zeile 17: | cp -v "$datei" "$zielordner/$jahr/$(basename "$datei").$datum"
|
Man kann auch noch den Dateinamen ohne basename rein in der Shell ermitteln: | cp -v "$datei" "$zielordner/$jahr/${datei##*/}.$datum"
|
☺
|
dingsbums
Anmeldungsdatum: 13. November 2010
Beiträge: 3532
|
rklm schrieb: Solche Command Substitutions wie in Zeile 4 gehen schief, sobald Leerzeichen oder andere in den Dateinamen vorkommen.
for datei in "$(find "$suchordner" -type f)";do Komplett gequotet geht es auch mit Leerzeichen. user@localhost:~$ ./script
'/home/user/quell ordner/das isn ordna/das is ne datei' -> '/home/user/ziel ordner/2018/das is ne datei'
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
dingsbums schrieb: rklm schrieb: Solche Command Substitutions wie in Zeile 4 gehen schief, sobald Leerzeichen oder andere in den Dateinamen vorkommen.
for datei in "$(find "$suchordner" -type f)";do Komplett gequotet geht es auch mit Leerzeichen.
Nee. | $ touch foo bar 'with space'
$ ls -1
bar
foo
'with space'
$ for datei in "$(find -type f)"; do echo ---; wc "$datei"; done
---
wc: './foo'$'\n''./bar'$'\n''./with space': No such file or directory
|
|
dingsbums
Anmeldungsdatum: 13. November 2010
Beiträge: 3532
|
Du hast recht. Mein Kopier-Beispiel
'/home/user/quell ordner/das isn ordna/das is ne datei' -> '/home/user/ziel ordner/2018/das is ne datei'
hat funktioniert, solange nur die Leerzeichen-im-Namen-Datei in diesem Ordner existiert. Kommt irgendeine Datei dazu, isses aus. Da darf ich wohl mal alle Skripte umändern. Puh ...
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
dingsbums schrieb:
Mein Kopier-Beispiel
'/home/user/quell ordner/das isn ordna/das is ne datei' -> '/home/user/ziel ordner/2018/das is ne datei'
hat funktioniert, solange nur die Leerzeichen-im-Namen-Datei in diesem Ordner existiert. Kommt irgendeine Datei dazu, isses aus. Da darf ich wohl mal alle Skripte umändern. Puh ...
Nein, es hat funktioniert, weil es nur ein Suchergebnis gab. Sobald die Anzahl der Suchergebnisse ungleich 1 ist und Du die gesamte Command Subsitution quotest, geht es schief - egal, ob irgendwo Leerzeichen in Dateinamen sind oder nicht. Ich erinnere noch mal an: rklm schrieb:
Generell ist es immer gut, wenn Du auch das Ergebnis der Anwendung postest, damit man sehen kann, was schief geht. Also, was passiert?
... und was ist das gewünschte Ergebnis?
|
dingsbums
Anmeldungsdatum: 13. November 2010
Beiträge: 3532
|
rklm schrieb: dingsbums schrieb: hat funktioniert, solange nur die Leerzeichen-im-Namen-Datei in diesem Ordner existiert. Kommt irgendeine Datei dazu, isses aus.
Nein, es hat funktioniert, weil es nur ein Suchergebnis gab.
Wir meinen eigentlich genau das Gleiche. Ich formuliere um: hat auch mit einer Leerzeichen-im-Namen-Datei funktioniert, solange in diesem Ordner keine weitere Datei existiert. ... und was ist das gewünschte Ergebnis?
Ich glaube, Du verwechselst mich gerade mit dem TE. Der hat sich ja leider nicht mehr gemeldet.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
dingsbums schrieb: rklm schrieb:
Nein, es hat funktioniert, weil es nur ein Suchergebnis gab.
Wir meinen eigentlich genau das Gleiche. Ich formuliere um: hat auch mit einer Leerzeichen-im-Namen-Datei funktioniert, solange in diesem Ordner keine weitere Datei existiert.
... und allen Unterordnern!
... und was ist das gewünschte Ergebnis?
Ich glaube, Du verwechselst mich gerade mit dem TE.
Nein.
Der hat sich ja leider nicht mehr gemeldet.
Ja.
|
dingsbums
Anmeldungsdatum: 13. November 2010
Beiträge: 3532
|
rklm schrieb: ... und was ist das gewünschte Ergebnis?
cabby79 schrieb: ich habe nachstehendes Skript:
...
getestet um Textdateien nach Änderungsdatum zu sortieren. Leider brachte dies nicht den erhofften Erfolg da tlw. Dateien von 2018 in 2017 landen.
Wenn ich den Eröffnungspost von cabby79 richtig deute, möchte er Dateien anhand des Modifikationsdatums in Jahresordner verschieben. Also noch einmal frisch ans Werk. Ich hoffe, das besteht jetzt vor Deinem prüfenden Blick. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | user@localhost:~$ mkdir -p "$HOME/quellordner/ordner mit leerzeichen"
user@localhost:~$ mkdir -p "$HOME/zielordner"
user@localhost:~$ touch -t 201101010100 "quellordner/ordner mit leerzeichen/datei aus dem jahr 2011"
user@localhost:~$ touch -t 201201010100 "quellordner/ordner mit leerzeichen/datei aus dem jahr 2012"
user@localhost:~$ touch -t 201301010100 "quellordner/ordner mit leerzeichen/datei aus dem jahr 2013"
user@localhost:~$
user@localhost:~$ export quellordner="$HOME/quellordner/ordner mit leerzeichen"
user@localhost:~$ export zielordner="$HOME/zielordner"
user@localhost:~$
user@localhost:~$ function move_to_jahresordner(){
> # jahr im format jjjj
> jahr=$(stat -c %y "$1" | cut -d '-' -f 1 )
> # jahresordner im zielordner anlegen
> mkdir -p "$zielordner"/"$jahr"
> # datei in passenden jahresordner verschieben
> mv -v "$1" "$zielordner/$jahr/$(basename "$1")"
> };
user@localhost:~$
user@localhost:~$ export -f move_to_jahresordner
user@localhost:~$
user@localhost:~$ find "$quellordner" -type f -exec bash -c 'move_to_jahresordner "$0"' {} \;
'/home/user/quellordner/ordner mit leerzeichen/datei aus dem jahr 2011' -> '/home/user/zielordner/2011/datei aus dem jahr 2011'
'/home/user/quellordner/ordner mit leerzeichen/datei aus dem jahr 2013' -> '/home/user/zielordner/2013/datei aus dem jahr 2013'
'/home/user/quellordner/ordner mit leerzeichen/datei aus dem jahr 2012' -> '/home/user/zielordner/2012/datei aus dem jahr 2012'
user@localhost:~$
user@localhost:~$ find zielordner/ -type f -exec ls -l {} \;
-rw-r--r-- 1 user user 0 Jan 1 2013 zielordner/2013/datei aus dem jahr 2013
-rw-r--r-- 1 user user 0 Jan 1 2012 zielordner/2012/datei aus dem jahr 2012
-rw-r--r-- 1 user user 0 Jan 1 2011 zielordner/2011/datei aus dem jahr 2011
user@localhost:~$
|
Bearbeitet von rklm: Bunte Konsole
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12802
|
dingsbums schrieb:
Wenn ich den Eröffnungspost von cabby79 richtig deute, möchte er Dateien anhand des Modifikationsdatums in Jahresordner verschieben.
Die Überschrift legt allerdings nahe, dass auch die Monate Verzeichnisse werden sollen.
Also noch einmal frisch ans Werk. Ich hoffe, das besteht jetzt vor Deinem prüfenden Blick.
☺ Passt schon. Man kann das auch mit date -r lösen. Dann kann man die Formatierungsfähigkeiten von date nutzen, z.B. mit ziel=ordner/$(date '+%Y/%m' -r "$file") oder halt nur ziel=ordner/$(date '+%Y' -r "$file") .
|