mikro110
Goto Top

Dateiname einer Datei um Wert aus einerCSV-Datei per Batch erweitern

Hallo an die Administratorenrunde. Ich benötige mal wieder eure Hilfe bei einer etwas kniffligen Angelegenheit. Leider habe ich im Netz bis jetzt keine Lösung gefunden.

Ich habe in einem Verzeichnis mehrere Dateien. Diese sind immer wie folgt aufgebaut:

Datei(1).MP3
Datei(1).CSV
Datei(2).MP3
Datei(2).CSV
Datei(3).MP3
Datei(3).CSV

Diese Dateien werden so beim Abspeichern von Audioaufzeichungen angelegt, wobei in den CSV-Datein immer die Verwaltungsdaten zum gleichnamigen Audiofile vorhanden sind.

Ich müßte nun die Dateinamen um einen Wert aus der entsprechenden CSV-Datei erweitern. Dieser steht immer in der der 2. Zeile der CSV-Datei als erster Wert (also vor dem ersten Komma).

Da es sich bei diesen Dateien durchaus um bis zu 100 Audioaufzeichnungen handelt, kann dieses schlecht von Hand erfolgen. Deshalb möchte ich dieses gerne über eine Batch-Datei realisieren.

Der Dateiordner, in dem die Dateien liegen, ist stehts ein anderer. Nach der Umbenennung sollten die Dateien wie folgt aussehen:

Datei_WertausCSV.PM3
Datei_WertausCSV.CSV
...


Ich hoffe, dass jemand dafür eine gute Idee hat.

Content-ID: 196663

Url: https://administrator.de/contentid/196663

Ausgedruckt am: 22.11.2024 um 18:11 Uhr

andimue
andimue 09.01.2013 aktualisiert um 12:45:38 Uhr
Goto Top
Hallo mikro110,

kannst du vielleicht mal den Inhalt einer csv-Datei posten?
Poste doch auch mal deinen Code, mit dem du es bisher versucht hast.

Oder willst du eine fertige Lösung haben face-wink (ich denke, du willst ja auch was lernen dabei oder )

Gruß Andi
Mikro110
Mikro110 09.01.2013 um 13:27:08 Uhr
Goto Top
Die CSV-Dateien schauen alle wie folgt aus (hinter XXX stehen andere Daten, die ich aber nicht veröffentlichen darf):

Startzeitpunkt,Endzeitpunkt,Dauer,Agent,Kanal,Eigene Telefonnummer,Partner-Telefonnummer,Weitere Telefonnummer,Kommentar,
09.Jan 2013 12:57:07,09.Jan 2013 12:57:45,00:00:38,XXX,XXX,XXX,XXX,,Unbekannt,

Mir geht es bei dieser Datei um den Eintrag "09.Jan 2013 12:57:07", wobei diese vermutlich so in einem Dateinamen nicht mal zulässig sind. Hier sollte dann "09Jan2013_125707" stehen, falls das möglich ist.

Einen Code habe ich noch nicht, da ich auf diesem Gebiet blutiger Anfänger bin. Gerne bin ich aber bereit zu lernen, da ich mich damit beruflich auseinandersetzen muss und grundsätzlich neugierig bin. face-smile

Also auch Ansätze dafür nehme ich gerne auf.
andimue
andimue 09.01.2013 aktualisiert um 15:15:10 Uhr
Goto Top
Blutigen Anfängern, die bereit sind zu lernen muss natürlich geholfen werden face-smile

@echo off & setlocal enabledelayedexpansion

set "dirpath=d:\temp"  
set "fileext1=csv"  
set "fileext2=mp3"  
set "filenameext="  

for /f %%a in ('dir /b %dirpath%\*.%fileext1%') do call :umbenennen %%a  
goto :EOF

:umbenennen 
for /f "delims=," %%b in ('more +1  %dirpath%\%1') do (  
		
		set "filenameext=%%b"  
		set "filenameext=!filenameext: =_!"  
		set "filenameext=!filenameext:.=_!"  
		set "filenameext=!filenameext::=!"  
	echo.
	echo    rename %dirpath%\%~n1.%fileext1% %~n1_!filenameext!.%fileext1%
	echo    rename %dirpath%\%~n1.%fileext2% %~n1_!filenameext!.%fileext2%
 )
goto :eof

zur Erklärung:

Zeile 03: Variable, die den Pfad zu den Dateien enthält
Zeile 04: Variable, die die erste zu bearbeitende Dateiende csv enthält
Zeile 05: Variable, die die zweite zu bearbeitende Dateiende csv enthält
Zeile 06: Variable, die den neu zu bildenden Dateinamenszusatz enthalten wird

Zeile 08: Schleife über die alle csv-Dateien im Pfad und mit jeder Datei eine Unterprozeudr aufrufen

Zeile 12: Zeile 2 (more +1) der übergebenden csv-Datei ausgeben und daraus den Wert vor dem ersten Komma entnehmen (deshalb der for-Befehl mit dem Zeichentrenner "delims=,")

Zeile 15: im Datum/Uhrzeitstring Blank durch _ ersetzen
Zeile 16: im Datum/Uhrzeitstring . durch _ ersetzen
Zeile 17: im Datum/Uhrzeitstring : entfernen

Zeile 19: umbennenen der csv-Datei
Zeile 20: umbennenen der mp3-Datei

Momentan ist das Umbennenen in Zeilen 19 + 20 durch den vorangestellten echo-Befehl noch deaktiviert, es wird nur der auszuführende Befehl ausgegeben.

Also mal die Zeile 3 anpassen und laufenlassen. Wenn alles paßt: den echo in Zeile 19 + 20 raus.

Es geht bestimmt noch eleganter, aber so funktioniert es jedenfalls erstmal

noch ein Hinweis: um das Skript kurz zu halten sind momentan keinerlei Prüfungen drin, also z.B. ob zu einer csv-Datei auch eine mp3 vorhanden ist oder wenn das Skript 2 mal läuft würde der Dateiname 2 mal um Datum/Uhrzeit ergänzt.

Gruß Andi
bastla
bastla 09.01.2013 um 17:45:59 Uhr
Goto Top
@ andimue
"delayedExpansion" ist gar nicht nötig - Du kannst ja nur den Timestamp in der Schleife holen und den Rest außerhalb erledigen - in einer Fassung, die auch mehr als 2 Zeilen in der csv-Datei und Dateinamen/Pfade mit Leerzeichen verträgt (und falls im Originaldateinamen kein "_" vorkommt, auch gleich das Mehrfach-Umbenennen verhindert) etwa so:
@echo off & setlocal

set "dirpath=d:\temp"  
set "fileext1=csv"  

for /f "delims=" %%a in ('dir /b "%dirpath%\*.%fileext1%"') do call :umbenennen "%%a"  
goto :eof

:umbenennen
echo %1|findstr "_">nul && goto :eof  

set "filenameext="  
for /f "delims=," %%b in ('more +1  "%dirpath%\%~1"') do if not defined filenameext set "filenameext=%%b"  
if not defined filenameext goto :eof
set "filenameext=%filenameext: =_%"  
set "filenameext=%filenameext:.=_%"  
set "filenameext=%filenameext::=%"  

echo ren "%dirpath%\%~n1.*" "%~n1_%filenameext%.*"  
goto :eof
Um nicht %dirpath% mitschleppen zu müssen, könntest Du vorweg
pushd "%dirpath%"
und nach der ersten Schleife das zugehörige
popd
verwenden.

Grüße
bastla
andimue
andimue 10.01.2013 um 07:49:38 Uhr
Goto Top
@ bastla
Ich bin dir für deine konstruktiven Vorschläge wirklich dankbar. Das du beim Imbennenen mit .* arbeitest und so nicht die %fileext2% brauchst find ich gut. Auch die Idee, in der 2.Schleife nur das Datum/Uhrzeit rauszuziehen und so auf den "delayedExpansion" zu verzichten macht die Sache einfacher und durchschaubarer.
Der Befehl echo %1|findstr "_">nul && goto :eof ist auch ne gute Sache um ein doppeltes Umbennenen zu verhindern (ich hatte ja wie geschrieben keine Prüfungen reingebaut, um Mikro110 nicht zu sehr zu verwirren).
Die Ergänzung um den "if not defined" in der 2.for-Schleife ist gut und sinnvoll. Ich bin laut der Beschreibung davon ausgegangen, dass die csv-Datei nur 2 Zeilen hat. Aber so ist es auf jeden Fall sicherer.
Zu pushd und popd: die beiden Befehle hab ich irgendwie so garnicht auf dem "Schirm" wenn ich Prozeduren schreibe. Aber ich sollte sie wohl dringend in mein Repertoire aufnehmen face-smile
Freundliche Grüße
Andi
Mikro110
Mikro110 10.01.2013 um 09:36:55 Uhr
Goto Top
Vielen Dank für die schnelle Hilfe.

@andimue
Grundsätzlich funktioniert das Umbenennen super. Nur wenn, wie in meinem Beispiel oben gezeigt, die Datei eine automatische Erweiterung "(1)" bekommen hat, dann funktioniert das Umbenennen leider nicht.
Mit der Batch von bastla funktioniert es hier hingegen aber auch. Kannst du bzw. bastla mir erklären wo hier der Unterschied liegt?

Zudem möchte ich die Erweiterung "(1)" usw. ebenfalls gleich entfernen. Gibt es dort einen Platzhalter für die Zahlen zwischen den Klammern? Ich hatte mir vorgestellt, dass ich dieses mit

set "filenameext=%filenameext: =%"

verwirklichen kann. Nur fehlt mir der Wert für die Klammern und Zahlenwert dazwischen, der durchaus dreistellig werden kann.
andimue
andimue 10.01.2013 um 10:50:59 Uhr
Goto Top
Hi Mikro110,

bastlas Prozedur funktioniert deshalb, weil er deutlich sauberer programmiert als ich face-wink
Er hat überall, wo der Dateiname vorkommt diesen in "" eingeschlossen, also z.B. hier:
for /f "delims=" %%a in ('dir /b "%dirpath%\*.%fileext1%"') do call :umbenennen "%%a"   
Er muss diese "" aber in der Unterprozeudr wieder entfernen und das macht er, indem er beim 2.for-Befehl diese Schreibweise nimmt: "%dirpath%\%~1" <-- hier kommt es auf die ~ an:

%~1 - Expandiert %1 und entfernt umschließende
Anführungszeichen (")

Erklärt wird dies in der Hilfe zum Befehl call ( also call /? am Prompt eingeben)

Für das Entfernen des Klammerteils aus dem Dateinamen kannst du z.B. den 2.for wie folgt abändern:
for /f "tokens=1,3 delims=()" %%a in ("%~n1_%filenameext%") do ren "%dirpath%\%~n1.*" "%%a%%b.*"  
Mikro110
Mikro110 10.01.2013 um 12:57:21 Uhr
Goto Top
Hallo andimue,

danke für die Erklärung. Jetzt habe selbst ich das verstanden. face-smile

Ich habe nun für das Entfernen der Klammern inklusive Inhalt die 2. for-Zeile wie oben beschrieben geändert. Dann funktioniert die Umbenennung mit den Werten aus der CSV-Datei nicht mehr und es wird auch nur z.B. die (1) entfernt. Die restlichen Dateien (2), (3) ... bleiben unverändert.
andimue
andimue 10.01.2013 um 14:23:15 Uhr
Goto Top
Sorry,
mein Fehler face-sad

Es muss nicht die 2.for-Schleife geändert werden sondern der ren-Befehl muss in eine for-Schleife eingebettet werden. Hier nochmals die Lösung von bastla mit der notwendigen Änderung

@echo off & setlocal

set "dirpath=d:\temp"  
set "fileext1=csv"  

for /f "delims=" %%a in ('dir /b "%dirpath%\*.%fileext1%"') do call :umbenennen "%%a"  
goto :eof

:umbenennen
echo %1|findstr "_">nul && goto :eof  

set "filenameext="  
for /f "delims=," %%b in ('more +1  "%dirpath%\%~1"') do if not defined filenameext set "filenameext=%%b"  
if not defined filenameext goto :eof
set "filenameext=%filenameext: =_%"  
set "filenameext=%filenameext:.=_%"  
set "filenameext=%filenameext::=%"  

for /f "tokens=1,3 delims=()" %%a in ("%~n1_%filenameext%") do echo ren "%dirpath%\%~n1.*" "%%a%%b.*"  
goto :eof
Mikro110
Mikro110 11.01.2013 um 07:17:25 Uhr
Goto Top
Moin andimue,

grundsätzlich scheint die Prozedur zu klappen. Es werden die Dateien leider nur nicht mehr umbenannt. Den Grund kann ich leider nicht sagen. Ich habe bis jetzt folgendes versucht:

1. Batch neu aus deinem obigen Eintrag kopiert
2. Rechner runtergefahren, stromlos gemacht und danach neu gestartet
3. Batch erneut eingerichtet
4. Pause-Befehl eingefügt vor letztem "goto :eof"

Durch den Pause-Befel konnte ich im CMD-Fenster folgendes sehen:

ren "d:\test\Test1(1).*" "Test1_09_Jan_2013_125707.*"

Dieses dann auch nochmal für die beiden 2. Testdateien Test1(2).

Führe ich den gleichen Befehlssatz mauell im CMD aus, so werden die Dateien auch richtig umbenannt. der Unterschied ist in der Darstellung nur, dass ich davor noch die üblichen C:\Users\Internet> stehen habe.

Hast du eine Idee, woran das liegen kann, dass der Befehlssatz manuell funktioniert, aber über den Batch nicht?
bastla
bastla 11.01.2013 um 07:25:12 Uhr
Goto Top
Hallo Mikro110!

Das "echo" in der Zeile 19 hast Du schon entfernt (zum Testen wird dadurch der "ren"-Befehl nur angezeigt)?

Grüße
bastla
Mikro110
Mikro110 11.01.2013 um 07:43:21 Uhr
Goto Top
Hallo Bastla,

dieses Echo habe ich total übersehen. Ich hatte nur auf den Beginn der jeweiligen Zeile geachtet.

Vielen Dank an euch beide. Es funktioniert super und ich habe wiede ne Menge dazugelernt.
andimue
andimue 11.01.2013 um 11:27:16 Uhr
Goto Top
Servus Mikro110,

Tschuldigung für die Verwirrung, die ich bei dir verursacht habe aber ich hab nur den rename-Befehl von bastla (mit echo) genommen und neu verpackt.
Aber wenn nun alles funktioniert ist es ja gut.

Grüße auch an bastla für seinen Input

Andi