dafosy
Anmeldungsdatum: 26. Februar 2012
Beiträge: 164
|
Hallo Community, habt ihr eine Idee, wie ich Dateien umbennenen kann und dabei auf Daten einer Tabelle zugreife. Habe schon einmal in krename geschaut, sehe dort aber keine richtige Möglichkeit. Folgendes Problem: (Namen geändert)
hiervon ausgehend
74086 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #17 - Anfang, Anton.pdf
74087 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #20 - Besser, Beate.pdf
74088 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #31 - Collm, Conrad.pdf
74089 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #33 - Dreber, David.pdf
74190 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #37 - Elch, Emil.pdf
74191 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #39 - Friedrich, Fiona.pdf
möchte ich zu
202312_AAN_Lohnjournal.pdf
202312_BBE_Lohnjournal.pdf
202312_CCO_Lohnjournal.pdf
202312_DDR_Lohnjournal.pdf
202312_EEL_Lohnjournal.pdf
202312_FFR_Lohnjournal.pdf
kommen. Nun denke ich an grep, join und/oder sed und ggf. einem Skript, welches erst alle Dateinamen mittels ls > verzeichnisinhalt.txt ermittelt und dann würde ich anfangen umzubauen. Eine mögliche Tabelle würde folgendes enthalten: Monat - hier: 202312 gelistete Zuordnung - hier AAN=Anfang, Anton; BBE=Besser, Beate; CCO=Collm,Conrad usw. Posrfix - hier: Lohnjournal
Aber vielleicht habt ihr eine bessere Idee? Grüße
dafosy
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4445
Wohnort: Göttingen
|
Irgendwie verstehe ich noch nicht, was da mit der Tabelle gemeint ist. Im Endeffekt möchtest Du doch einfach nur die Dateien umbenennen nach gegebenem Schema, oder nicht?
|
dafosy
(Themenstarter)
Anmeldungsdatum: 26. Februar 2012
Beiträge: 164
|
Richtig, ich möchte die Dateinamen nach dem Schema umbenennen. Allerdings das Skript auf einen ganzen Ordner ansetzen. Und da muss ja irgendwie eine Zuordnung erfolgen nach dem
Namen - Kürzel Schema und monatlich ändert sich ja auch der "Lohnauswertungen vom 10.01.2024 _ 13_44" Teil.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11233
Wohnort: München
|
Den neuen Namen zu finden ist recht schnell erledigt:
| #!/usr/bin/env python3
import datetime
import re
import fileinput
FILENAME_PARSE_RE = re.compile(r'\d+ - Lohnauswertungen vom (?P<date>\d{2}\.\d{2}\.\d{4}) _ \d+_\d+ - #\d+ - (?P<first>\S).*, (?P<last>\S{2})')
for line in fileinput.input():
if m := FILENAME_PARSE_RE.match(line):
data = m.groupdict()
dt = (datetime.datetime.strptime(data['date'], "%d.%m.%Y") - datetime.timedelta(days=30)).strftime("%Y%m")
print(f"{dt}_{data['first'].upper()}{data['last'].upper()}_Lohnjournal.pdf")
|
$ python name_converter.py << EOF
74086 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #17 - Anfang, Anton.pdf
74087 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #20 - Besser, Beate.pdf
74088 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #31 - Collm, Conrad.pdf
74089 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #33 - Dreber, David.pdf
74190 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #37 - Elch, Emil.pdf
74191 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #39 - Friedrich, Fiona.pdf
EOF
202312_AAN_Lohnjournal.pdf
202312_BBE_Lohnjournal.pdf
202312_CCO_Lohnjournal.pdf
202312_DDA_Lohnjournal.pdf
202312_EEM_Lohnjournal.pdf
202312_FFI_Lohnjournal.pdf Dann kann man das Skript auch gleich über eines oder mehrere Verzeichnisse laufen lassen, die man als Argument übergibt (wenn man nichts angibt, durchsucht es das aktuelle Verzeichnis): 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 | #!/usr/bin/env python3
import fileinput
import re
import sys
from datetime import datetime, timedelta
from pathlib import Path
FILENAME_PARSE_RE = re.compile(r'\d+ - Lohnauswertungen vom (?P<date>\d{2}\.\d{2}\.\d{4}) _ \d+_\d+ - #\d+ - (?P<first>\S).*, (?P<last>\S{2})')
def rename_files_in_folder(folder: str):
for f in Path(folder).glob('*.pdf'):
if not f.is_file():
print(f"{f} is not a file, ignoring", file=sys.stderr)
continue
if m := FILENAME_PARSE_RE.match(f.name):
data = m.groupdict()
dt = (datetime.strptime(data['date'], "%d.%m.%Y") - timedelta(days=30)).strftime("%Y%m")
new_name = f.parent / f"{dt}_{data['first'].upper()}{data['last'].upper()}_Lohnjournal.pdf"
print(f"renaming {f} -> {new_name}")
f.rename(new_name)
else:
print(f"Warning: file '{f}' doesn't match expected name schema", file=sys.stderr)
if __name__ == '__main__':
for arg in sys.argv[1:]:
rename_files_in_folder(arg)
else:
rename_files_in_folder('.')
|
Wenn man es ausführbar macht, sieht der Aufruf dann z.B. so aus:
./rename_files.py /pfad/zum/Ordner
Wenn man die Verzeichnisse rekursiv durchlaufen will, ersetzt man glob('*.pdf') durch rglob('*.pdf') .
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1214
|
Könnte es sein, dass du folgendes meinst?
~/x$ ls -1
'74086 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #17 - Anfang, Anton.pdf'
'74087 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #20 - Besser, Beate.pdf'
'74088 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #31 - Collm, Conrad.pdf'
'74089 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #33 - Dreber, David.pdf'
'74190 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #37 - Elch, Emil.pdf'
'74191 - Lohnauswertungen vom 10.01.2024 _ 13_44 - #39 - Friedrich, Fiona.pdf'
Target
~/x$ # Nun werden die Dateien in das Verzeichnis "Target" kopiert
~/x$ ls -1 *.pdf | awk -v Tdir="Target" '{split($5,arr,".");print "cp \""$0"\" "Tdir"/"arr[3] arr[2]"_"substr($12,1,1) toupper(substr($11,1,2))"_Lohnjournal.pdf"}' | bash -
~/x$ ls -1 Target/
202401_AAN_Lohnjournal.pdf
202401_BBE_Lohnjournal.pdf
202401_CCO_Lohnjournal.pdf
202401_DDR_Lohnjournal.pdf
202401_EEL_Lohnjournal.pdf
202401_FFR_Lohnjournal.pdf
~/x$
Man kann das auch mittels "sed" machen, aber awk war mir hierfür geeigneter. Statt dem "cp" kannst du natürlich auch ein "mv" machen. PS:
Wenn du als Datum des "10.01.2024" den um einen Monat reduzierten Wert (202312) stehen haben willst, kannst du das über die "awk" Funktionen "mktime" und "strftime" erreichen:
ls -1 *.pdf | awk -v Tdir="Target" '{split($5,arr,".");print "cp \""$0"\" "Tdir"/"strftime("%Y%m",mktime(arr[3]" "arr[2]" "arr[1]" 00 00 00")-30*24*60*60)"_"substr($12,1,1) toupper(substr($11,1,2))"_Lohnjournal.pdf"}'
|
dafosy
(Themenstarter)
Anmeldungsdatum: 26. Februar 2012
Beiträge: 164
|
Moin seahawk, Und da ist python wieder ... vielleicht steige ich da wirklich mal ein, denn dein Skript gefällt mir. Das erledigt quasi alles ohne Tabelle und Kram und baut die Namen dann auch gleich zusammen. Ich danke dir und fuchs mich mal rein in die Skriptlogik. /dafosy
|
dafosy
(Themenstarter)
Anmeldungsdatum: 26. Februar 2012
Beiträge: 164
|
@shiro auch ein guter Ansatz
|
wxpte
Anmeldungsdatum: 20. Januar 2007
Beiträge: 1388
|
dafosy schrieb: Das erledigt quasi alles ohne Tabelle und Kram und baut die Namen dann auch gleich zusammen.
Das setzt natürlich voraus, dass die Kürzel streng diesem Schema folgen, und bei einer Vielzahl von Namen keine Doppelungen auftreten. Wenn du nämlich zum Beispiel Anfang, Anton und Anders, Alfred hast, dann bekommst du für beide das Kürzel AAN . Aber wenn du damit zufrieden bist, OK.
|
wxpte
Anmeldungsdatum: 20. Januar 2007
Beiträge: 1388
|
Das wäre nun mein Ansatz:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #!/bin/bash
basis=/Pfad/zum/Skriptverzeichnis
datenv=/Pfad/zum/Verzeichnis/Lohnjournal
for langdat in $datenv/*Lohnauswertungen*; do
tist=$(grep -Eo '([0-9]{2}\.){2}[0-9]{4}' <<< "$langdat" | sed -E 's/([0-9]{2})\.([0-9]{2})\.([0-9]{4})/\3-\2-\1/')
mon=$(date -d"$tist 1 month ago" '+%Y%m')
while read kurzdat; do
nlang=$(cut -f1 -d';' <<< $kurzdat)
if grep -q "$nlang" <<< "$langdat"; then
nkurz=$(cut -f2 -d';' <<< $kurzdat)
fi
done < $basis/Kuerzel.tbl
cp "$langdat" $datenv/${mon}_${nkurz}_Lohnjournal.pdf
done
|
Vorausgesetzt die Namensliste Kuerzel.tbl ist sauber gepflegt:
Anfang, Anton;AAN
Besser, Beate;BBE
Collm, Conrad;CCO
Dreber, David;DDR
Elch, Emil;EEL
Friedrich, Fiona;FFR gibt es für jede Person ein einmaliges Kürzel. Außerdem berücksichtigt das Skript auch, dass das Lohnjournal jeweils den Vormonat des im Langnamen angegebenen Timestamps auswertet.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17593
Wohnort: Berlin
|
| cat lohn.txt | while read fnam
do
nam=$(echo "$fnam" | sed -r 's/.*#[^A-Z]+([A-Z])[^A-Z]+, ([A-Z][a-z]).*\.pdf/\1\2_Lohnjournal.pdf/')
tag=$(echo $fnam | cut -d " " -f 5)
m=${tag:3:2}
y=${tag/*./}
echo mv "$fnam" $y${m}_$nam
done
|
|
dafosy
(Themenstarter)
Anmeldungsdatum: 26. Februar 2012
Beiträge: 164
|
Ich danke euch allen. Die Lösung von @wxpte kommt meinem Problem recht nahe und das teste ich gerade. Insbesondere mit der Option den Vormonat zu nutzen, ist sinnvoll. Danke! /dafosy
|