ubuntuusers.de

Dateien umbenennen - anhand Informationen in Tabelle

Status: Gelöst | Ubuntu-Version: Kubuntu 22.04 (Jammy Jellyfish)
Antworten |

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:

  1. Monat - hier: 202312

  2. gelistete Zuordnung - hier AAN=Anfang, Anton; BBE=Besser, Beate; CCO=Collm,Conrad usw.

  3. Posrfix - hier: Lohnjournal

Aber vielleicht habt ihr eine bessere Idee?

Grüße dafosy

Doc_Symbiosis

Avatar von 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

  1. Namen - Kürzel Schema und

  2. 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/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

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17593

Wohnort: Berlin

1
2
3
4
5
6
7
8
9
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

Antworten |