如何用PowerShell批量修改目录内文件的编码与扩展名?
Hi there! You're off to a great start with the single-file and standalone rename commands—let's get your batch processing working properly. Let's first break down why your existing code isn't running, then walk through working solutions.
Why Your Existing Code Failed
Let's look at the issues in your attempts:
- Broken loop syntax: Your first batch attempt
$a = dir | $a foreach-object | get-content | set-content -encoding utf8 $a_fullname.xmlhas incorrect PowerShell syntax. You can't assign a variable mid-pipe like that, andforeach-objectneeds to be used as a command in the pipeline, not attached to a variable. - Misusing pipeline parameters: After
Rename-Item, you tried adding-encoding utf8directly to the pipeline—but-encodingis a parameter for commands likeSet-Content, not a standalone command. The pipeline afterRename-Itempasses file objects, not file content, so this won't work.
Working Solutions
We'll cover two common scenarios: creating new UTF-8 files with the .xml extension (keeping original .txt files), or modifying the original files (updating encoding then renaming).
Scenario 1: Create New UTF-8 .xml Files (Keep Original .txt)
This reads each .txt file, saves its content as UTF-8 to a new .xml file, leaving your original files intact:
# Get all .txt files in the current directory Get-ChildItem -Filter *.txt | ForEach-Object { # Read the content of the current file $fileContent = Get-Content -Path $_.FullName # Create the new filename by replacing .txt with .xml at the end of the path $newFilePath = $_.FullName -replace '\.txt$', '.xml' # Save the content as UTF-8 to the new .xml file Set-Content -Path $newFilePath -Encoding UTF8 -Value $fileContent }
Notes for this script:
- Use
\in the regex replacement to escape the dot (.matches any character in regex), and$to ensure we only replace the final.txtextension (avoids issues with filenames likenotes.txt.bak). - If your original .txt files use a non-default encoding (like GB2312), add
-EncodingtoGet-Contentto read them correctly—e.g.,Get-Content -Path $_.FullName -Encoding GB2312. - In PowerShell 5+,
-Encoding UTF8creates BOM-less UTF-8 files. If you need a UTF-8 BOM, use-Encoding UTF8BOMinstead.
Scenario 2: Modify Original Files (Update Encoding + Rename)
If you want to overwrite the original .txt files with UTF-8 encoding, then rename them to .xml:
Get-ChildItem -Filter *.txt | ForEach-Object { # First, update the original file's encoding to UTF-8 $fileContent = Get-Content -Path $_.FullName Set-Content -Path $_.FullName -Encoding UTF8 -Value $fileContent # Then rename the file to .xml Rename-Item -Path $_.FullName -NewName ($_.Name -replace '\.txt$', '.xml') }
Bonus: Process Files in Subdirectories
Add the -Recurse parameter to Get-ChildItem to handle .txt files in all subfolders:
Get-ChildItem -Filter *.txt -Recurse | ForEach-Object { # Same logic as above goes here }
Quick Recap of Key Concepts
ForEach-Object(can be shortened to%for brevity) lets you run commands on every object in the pipeline—this is how you batch process files.$_.FullNamegives you the full path of the current file in the loop, while$_.Nameis just the filename without the path.- Always use regex carefully when replacing extensions—
-replace '\.txt$', '.xml'is safer than simple string replacement because it targets only the ending .txt.
内容的提问来源于stack exchange,提问作者MrShakur

