ich habe einige Probleme beim Erstellen eines Skripts, das in jeder Datei in einem Ordner einen bestimmten Text findet, den Inhalt nach diesem Text abruft und ihn als Namen für die Datei festlegt, und das alles innerhalb einer Schleife, um dasselbe für mehrere Dateien auszuführen.
Beispiel: Ich habe einen Ordner mit Datei1, Datei2, Datei3
content in file1: sw_part = "ABC-DEF.GHJ";
content in file2: sw_part = "ABC-123.XYZ";
content in file3: sw_part = "ABCDE-FGHJ.KLMN";
Das Ergebnis sollte sein:
file1 renamed to ABC-DEF.GHJ
file2 renamed to ABC-123.XYZ
file3 renamed to ABCDE-FGHJ.KLMN
Was ich gemacht habe, ist Folgendes:
for /F "tokens=2 delims==" %%a in ('findstr /I "sw_part" file1') do set "swpart=%%a"
echo sw part is: %swpart%
copy file1 "%swpart%"
Das funktioniert gut, aber nur für eine bestimmte Datei (ich kann es nicht mit einer Schleife zum Laufen bringen) und es benennt die Datei auch mit;
am Ende. Irgendeine Hilfe?
Dies muss im Batch-Verfahren erfolgen. PowerShell ist auch ok.
Danke
Antwort1
Das folgende Skript erledigt das Gewünschte.
cd C:\temp\swpart
$files = [System.Collections.ArrayList]@()
select-string -Path "*.*" -Pattern "sw_part" | ForEach-Object {
$old_filename = $_.Filename
$new_filename = $_.line -replace "^.*sw_part = ""","" -replace """.*$",""
# put everything in array, so the files get closed and can be renamed later.
$null = $files.Add(@{"old"=$old_filename;"new"=$new_filename})
}
$files |ForEach-Object{
$old_filename = $_.old
$new_filename = $_.new
rename-item $old_filename $new_filename -Force
}
Stellen Sie sicher, dass Sie die erste Zeile ändern, um den Pfad zu ändern, in dem sich die Dateien befinden.
Wenn aus irgendeinem Grund nicht alle Dateien umbenannt werden, führen Sie das Skript erneut aus. Dann wurde die Datei noch verwendet.
Antwort2
- Mit PowerShell ist dies auch mit nur zwei Zeilen möglich:
ls 'F:\2020-SU\Q1605996\*.txt'|%{$new=(cat $_.FullName).split('\"*\"')[-2];ren $_.FullName -new $new -force}
- Ohne Aliase zu verwenden:
Get-ChildItem 'F:\2020-SU\Q1605996\*.txt' | ForEach {
$new=(Get-Content $_.FullName).split('\"*\"')[-2]
Rename-Item $_.FullName -new $new -force
}
- Sie können dies auch mit cmd in nur einer Zeile tun:
In der Befehlszeile:
for /f tokens^=1-3delims^=^:^"^" %a in ('findstr . *.txt')do @ren "%~fa" "%~c"
In der Bat/cmd-Datei:
@echo off
cd /d "C:\Path\To\Your\Folder"
for /f tokens^=1-3delims^=:^"^" %%a in ('findstr . *.txt')do @ren "%%~fa" "%%~c"
Findstr
Befehl und Ausgabe
>F:\Q1605996>findstr . *.txt
file1.txt:sw_part = "ABC-DEF.GHJ";
file2.txt:sw_part = "ABC-123.XYZ";
file3.txt:sw_part = "ABCDE-FGHJ.KLMN";
file4.txt:sw_part = "ABCDE-FGHJ.KXMN";more test/strings
file5.txt:this is a test; sw_part = "fea.geow.eaf.gae"; this is another test;
For
Loop-Befehlsmechaniker
set yours delimiters : + " + " ==>> delims^=:^"^"
set yours tokens "1" - "3" ==>> tokens^=1-3
: = ;
token = 1:token =2= token = 3;
file1.txt:sw_part = "ABC-DEF.GHJ" ;
file2.txt:sw_part = "ABC-123.XYZ" ;
file3.txt:sw_part = "ABCDE-FGHJ.KLMN";
file4.txt:sw_part = "ABCDE-FGHJ.KXMN";more test/strings
| | | |
ren "%f~a" "%~c"
ren "F:\Q1605996\file1.txt" "ABC-DEF.GHJ"
ren "F:\Q1605996\file2.txt" "ABC-123.XYZ"
ren "F:\Q1605996\file3.txt" "ABCDE-FGHJ.KLMN"
ren "F:\Q1605996\file4.txt" "ABCDE-FGHJ.KXMN"
rem :: The same in file5.txt
file5.txt:this is a test;sw_part = "fea.geow.eaf.gae"; this is another test;
| | | |
ren "%f~a" "%~c"
ren "F:\Q1605996\file5.txt" "fea.geow.eaf.gae"
Zusätzliche Ressourcen PowerShell:
Split()
Replace()
Substring()
Rename-Item
|ren
ForEach-Object
|%
|?
Get-Content
|type
|cat
Get-ChildItem
|ls
|dir
Zusätzliche Ressourcen cmd/batch: