internet2107
Goto Top

Finden von (fast) gleichen Dateinamen, Ändern von Dateinamen

Ich habe leider mal wieder eine etwas knifflige Sache.

Aktuell suche ich in Verzeichnissen nach Dateien mit gleichen Namen und erstelle daraus eine neue Datei.
In meinem Fall suche ich nach _used.dat Dateien die vom Dateinamen genauso sind, wie xlsb-Dateien.

Nun kommt aber folgendes Problem dazu, dass in den neuen .used-dat Dateien Änderungen hinzugekommen sind, die aber nun wieder entsprechend angepasst werden sollen, damit am Ende wieder das (wie bisher) selbe Ergebnis bei rauskommt.

Mit anderen Worten.
Bisher gibt es z.B. in einem Verzeichnis 2 Dateien:

output_2 (file 2) (2238269xxx) (2_3d) (19270250)_USED.DAT
output_2 (file 2) (2238269xxx) (2_3d) (19270250).xlsb

In dem Code unten sucht er nach den Dateien, vergleicht diese und wenn beide denselben Namen haben, wird entsprechend daraus eine (neue) xlsb-Datei gemacht.


Nun aber hat sich die Ausgabe geändert. Die Dateien sehen nun so aus:

output-2 (file 2) (2238269xxx) (2-3d) (19270250) (05282014)_USED.DAT
output_2 (file 2) (2238269xxx) (2_3d) (19270250).xlsb

Wie man sieht, unterscheiden sich die beiden Dateien nun soweit, dass in der neuen "dat-Datei" das (-)-Zeichen gegen einen (_) getauschen werden muss und dazu die letzte Klammer mit der Zahl wieder raus muss.
Da die Zahl in der Klammer sich ändert, wäre eine Löschung vor dem "_used.dat" bis zum Ende der nächsten Klammer perfekt.

Kann mir hier jemand helfen ?

		
$DATDateien = Get-ChildItem -Path $path -include *_USED.DAT -recurse
		
		$XLSBDateien = Get-ChildItem -Path $path -include *.xlsb -recurse
				
		$excelFiles = ForEach ($xls in $DATDateien)
		{
			ForEach ($xlsb in $XLSBDateien)
			{
				If ($xls.BaseName -eq $xlsb.BaseName)
				{
					$xlsb
				}
			}
		}

Content-Key: 252010

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

Printed on: April 24, 2024 at 15:04 o'clock

Member: colinardo
colinardo Oct 15, 2014, updated at Oct 18, 2014 at 08:32:07 (UTC)
Goto Top
Hi,
weis nicht ob ich es richtig interpretiert habe aber das ließe sich so machen:
wird entsprechend daraus eine (neue) xlsb-Datei gemacht.
was du damit meinst, ob umbenennen oder kopieren konnte ich nicht interpretieren. denke aber mit unten stehendem Code solltest du dein Problem lösen können.
$path = 'c:\deinPfad'  
dir $path -Include '*.xlsb' -Recurse | %{  
    # passende DAT Datei suchen
    $dat = dir "$path\$($_.BaseName.Replace('_','-'))*_USED.DAT" -Recurse | select -First 1  
    # wenn eine zur xlsb-Datei passende DAT-Datei gefunden wurde
    if ($dat){
        write-host "Für folgende Datei wurde eine USED-DAT gefunden:"$_.FullName  
    }
}
Grüße Uwe
Member: internet2107
internet2107 Oct 15, 2014 at 13:18:04 (UTC)
Goto Top
Hallo lieber Uwe,

dank dir erstmal für die schnelle Antwort.
Werde ich gleich mal ausprobieren.
Wichtig ist nur, dass die Umbenennung der "dat" Datei nicht auf File-Ebene passieren darf, es dürfen also nicht die Originaldateien im Ordner umbenannt werden, sondern lediglich in einer Art Variable, aus der dann letztendlich eine xlsb wird.

Ich schaue gleich mal.

Danke dir erstmal!!!
Member: internet2107
internet2107 Oct 16, 2014 updated at 07:59:49 (UTC)
Goto Top
Guten Morgen,

ich hatte nun endlich Zeit das mal genau zu testen, jedoch macht er noch nicht genau das, was er soll, oder mir fehlt der Kaffee um den Wald vor lauter Bäumen zu sehen ??

Dein Script klappt soweit, dass er den Namen der dat-Datei entsprechend ändert, indem Fall die nicht gewünschte Klammer mit der Zahl entfernt, ebenso aus den (-)-Zeichen ein (_)-Unterstrich macht.
Ebenso die xlsb Datei mit der dat-Datei vergleicht und auch entsprechend die jeweils richtige filtert.

Um es noch mal etwas zu verdeutlichen.
Bisher hat er in diesem Ordner immer nach xls-Dateien gesucht, dann die Endung .xls entfernt und den Namen mit der im selben Ordner befindlichen xlsb-Datei verglichen. War der Name beider Dateien derselbe, hat er die xls-Datei genommen und daraus über Excel einen Ausdruck generiert.
Leider sind nun die xls-Dateien rausgefallen und wurden durch die _used.dat Dateien "ersetzt". Die _used.dat Dateien haben aber nun den Unterschied, dass sie zuerst ein (-)Zeichen, anstatt ein Unterstrich haben, dazu hat die bekannte Klammer mit Zahlen und die Bezeichnung "_used".

Am Ende erstellt das Script aus der xlsb-Datei einen Ausdruck.

Was aber noch nicht ganz sauber klappt, ist:
- er schreibt im Host, dass er 2 Dateien gefunden hat, er druckt dann aber 9x nur einer der beiden xlsb Dateien aus.

Schaue ich im Ordner nach, liegen dort insgesamt 9 dat-Dateien, davon 8x = _used.dat und 1x = .dat
Aber nur 2 xlsb-Dateien.
Richtig wäre aber, indem er nur die beiden dat-Dateien nimmt, die auch vom Namen mit den xlsb-Dateien übereinstimmen. Vielleicht habe ich heute Morgen noch Tomaten auf den Augen den Fehler zu sehen, darum paste ich mal das soweit geänderte und passende Script:

$path = $folder.Self.Path
$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type]  
		
	
		# zeige nur _used.DAT Dateien
		$DATDateien = Get-ChildItem -Path $path -include *.dat -recurse
		# zeige nur XLSB Dateien
		$XLSBDateien = Get-ChildItem -Path $path -include *.xlsb -recurse
				
		# Für jede *_used.dat Datei in der Liste (Array) wird etwas gemacht
		$excelFiles = ForEach ($_used_dat in $DATDateien)
		{
			dir $DATDateien | ForEach {
				# passende DAT Datei suchen
				$dat = dir "$path\$($_.BaseName.Replace("_","-"))*_USED.DAT" -Recurse | select -First 1  
				# wenn eine zur xlsb-Datei passende DAT-Datei gefunden wurde
				if ($dat)
				{
					# DAT Name anpassen
					$newDATName = $dat.Name -replace '\s*\(\d+\)_USED.DAT$', ''  
					write-host 'Passende DAT-Datei gefunden: '$dat.Fullname  
					$newDATName_ready = $newDATName.Replace("-", "_")  
					write-host 'Geänderter Name der DAT-Datei: '$newDATName_ready  
					Write-Host $_used_dat
				}
			}
			
			
			# Für jede *.xlsb Datei in der Liste (Array) wird etwas gemacht
			ForEach ($xlsb in $XLSBDateien)
			{
				# vergleichen ob die Aktuell verarbeitete *_used.dat Datei den selben Namen hat
				# wie die Aktuell verarbeitete *.xlsb Datei
				If ($newDATName_ready -eq $xlsb.BaseName)
				{
					# passende Datei ausgeben
					$xlsb
				}
			}
		}
		
		
		$objExcel = New-Object -ComObject excel.application
		$objExcel.visible = $false
		
			$buttonStudieAuswahl.Enabled = $false
			$buttonStartJob.Enabled = $false
			$buttonPDFaErzeugen.Enabled = $false
			$buttonexit.Enabled = $false
		foreach ($wb in $excelFiles)
		{
		# ab hier werden die Ausdrucke generiert, nachdem sie in Excel formatiert wurden.
Member: colinardo
colinardo Oct 16, 2014 updated at 09:47:43 (UTC)
Goto Top
für mein Script benötigst du nur eine Schleife, nämlich nur über die xlsb-Dateien.
Diese Zeile:
$dat = dir "$path\$($_.BaseName.Replace("_","-"))*_USED.DAT" -Recurse | select -First 1 
sucht dann dazu die passende DAT zur xlsb heraus. Du machst es bei dir doppelt gemoppelt mit zwei Schleifen, die sind dann überflüssig!
Member: internet2107
internet2107 Oct 18, 2014 updated at 08:21:07 (UTC)
Goto Top
Hi lieber Uwe,

sorry, dass ich mich erst wieder heute melde.
Wie gesagt funktioniert dein Script ja auch soweit, aber dennoch noch mal:

Ist-Stand:
Dein Script gibt NUR!!! die DAT-Dateien aus, was aber nicht der Fall sein soll. Dein Script ändert dazu zuviel, löscht zuviel weg, was es nicht soll.

Soll-Stand:
Es sollen NUR!! die passenden Xlsb-Dateien ausgegeben werden, die zum jeweiligen Namen der DAT-Datei passen.
Es soll nur die letzte Klammer von hinten entfernt werden.


In dem jeweiligen Suchordner befinden sich bis zu 10.000 Dateien. Diese werden von einer Maschine ausgeworfen. Durch das Filtern von "xlsb" und "_used.dat" schränken wir die Suche schon mal sehr groß ein, fallen mehrere Tausend dabei raus..
Dennoch gibt es aber z.B. eine _used.dat-Datei mit dem Namen:

T101361-3 (Test 3) (2281698) (2-3h) (19270243) (05282014)_USED.DAT
T101361-3 (Test 3) (2281698) (2-3h) (19270243) (routine) (05282014)_USED.DAT
T101361-3 (Test 3) (2281698) (2-3h) (19270243) (k) (05282014)_USED.DAT

dazu die jeweiligen xlsx-dateien:

T101361_3 (Test 3) (2281698) (2_3h) (19270243).xlsb
T101361_3 (Test 3) (2281698) (2_3h) (19270243) (routine).xlsb
T101361_3 (Test 3) (2281698) (2_3h) (19270243) (k).xlsb

Wichtig ist also, dass NUR!! die letzte Klammer und deren Inhalt von hinten aus gerechnet entfernt wird.
Nehme ich dein aktuelles Script, wird auch die (routine) oder das (k) mit entfernt???

Und letztendlich soll nicht die DAT-Datei weiter verarbeitet werden, sondern nur die XLSB.
In Beispiel oben sollte im Idealfall eine Ausgabe der 3 xls-Dateien ausgegeben werden, dann erfolgt ein Druck.

Das Umbenennen der DAT-Datei usw. funktiniert ja auch in deinem Script. Dieses Umbenennen erfolgt, oder soll, ja nur "virtuell" erfolgen, damit ein Namenvergleich zwischen der jeweiligen _used.dat und der xls-Datei erfolgen kann, um so die xls-Datei auszugeben.
Member: colinardo
Solution colinardo Oct 18, 2014 updated at 08:36:31 (UTC)
Goto Top
Zitat von @internet2107:
Wichtig ist also, dass NUR!! die letzte Klammer und deren Inhalt von hinten aus gerechnet entfernt wird.
Nehme ich dein aktuelles Script, wird auch die (routine) oder das (k) mit entfernt???
Nein das tat es nicht face-wink ist eine Regular Expression dir nur das letzte Klammernpaar entfernte.
Und letztendlich soll nicht die DAT-Datei weiter verarbeitet werden, sondern nur die XLSB.
alle klar, dann sag das doch gleich face-smile
Ist oben nach deinen Wünschen angepasst ...
Member: internet2107
internet2107 Oct 21, 2014 updated at 09:42:33 (UTC)
Goto Top
Lieber Uwe,

kann man das hier ebenso noch mal weiter eingrenzen ?

dir $path -Include '*.xlsb' -Recurse | %{  
    # passende DAT Datei suchen
    $dat = dir "$path\$($_.BaseName.Replace('_','-'))*_USED.DAT" -Recurse | select -First 1  

worauf ich hinaus will: alleine das Wort: -filter ist mehr als 10x so schnell, als -include.
Man nehme ein Ordner, indem sich wie bekannt mehr als 10.000 Dateien befinden, davon alleine 1000 _used.dat und 1800 .xlsb
Diese Dateien liegen im Netz. Alleine das Vergleichen der Dateien dauert Ewigkeiten...

kann man das auch auf das Wort _used.dat filtern ?

also im Endeffekt so etwas wie:

dir $path -filter '*.xlsb' -Recurse | %{  
    # passende DAT Datei suchen
    $dat = dir "$path -filter \$($_.BaseName.Replace('_','-'))*_USED.DAT" -Recurse | select -First 1  
Member: colinardo
Solution colinardo Oct 21, 2014 updated at 09:56:59 (UTC)
Goto Top
Klar kannst du machen
dir $path -filter '*.xlsb' -Recurse | %{  
    # passende DAT Datei suchen
    $dat = dir $path -filter "$($_.BaseName.Replace('_','-'))*_USED.DAT" -Recurse | select -First 1