PowerShell - 批量更改文件编码为UTF-8 [英] PowerShell - Batch change files encoding To UTF-8

查看:521
本文介绍了PowerShell - 批量更改文件编码为UTF-8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个简单的事情:将文件编码从任何东西改为UTF-8而没有BOM。我发现了几个这样做的脚本,唯一一个真正适合我的脚本是这样的: https://superuser.com/questions/397890/convert-text-files-recursively-to-utf-8-in-powershell#answer-397915



它按预期工作,但是我需要没有BOM的生成的文件。所以我试图修改脚本一点,添加了这个问题的解决方案:使用PowerShell在没有BOM的情况下以UTF-8编写文件



这是我的最终脚本:

  foreach($ i in Get-ChildItem -Recurse){
if($ i.PSIsContainer) {
continue
}

$ dest = $ i.Fullname.Replace($ PWD,some_folder)

$ Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($ False)

if(!(Test-Path $(Split-Path $ dest -Parent))){
New-Item $(Split-Path $ dest -Parent)类型目录
}

get-content $ i | out-file -encoding $ Utf8NoBomEncoding -filepath $ dest
}

问题是,向我发送一个错误,关于 System.Text.UTF8Encoding($ False)行,抱怨一个不正确的参数:



不能验证'Encoding'参数的参数。参数System.Text.UTF8Encoding不属于由ValidateSet属性指定的组unicode,utf7,utf8,utf32,ascii。



我想知道我是否缺少某些东西,如PowerShell版本或类似的东西。我从来没有编写过Powershell脚本,所以我完全失去了这一点。而且我需要修改这些文件编码,有几百个,我不想自己一个个。



其实我使用的是2.0 Windows 7附带的版本。



提前感谢!



编辑1



我尝试了以下代码,由@LarsTruijens和其他帖子建议:

  $ Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($ False)
foreach($ i in Get-ChildItem -Recurse){
if($ i.PSIsContainer){
继续
}

$ dest = $ i.Fullname.Replace($ PWD,some_folder)

if(!(Test-Path $(Split- Path $ dest -Parent))){
New-Item $(Split-Path $ dest -Parent) - 类型目录
}

$ content = get-content $ i
[System.IO.File] :: WriteAllLines($ dest,$ content,$ Utf8NoBomEncoding)
}

这给我一个异常,抱怨一个参数用于WriteAllLines的代码:使用3个参数调用WriteAllLines异常。该值不能为空参数名称:contents 脚本创建所有文件夹,但都为空。



编辑2



这个错误的一个有趣的事情是content参数不为null如果我输出$ content的值变量(使用Write-host)行,那么为什么当它传递给WriteAllLines方法时变为null?



编辑3



我已经向变量添加了内容检查,因此脚本现在如下所示:

 code> $ Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($ False)
foreach($ i in Get-ChildItem -Recurse){
if($ i.PSIsContainer){
continue
}

$ dest = $ i.Fullname.Replace($ PWD,some_folder)

if(!(Test-Path $ Split-Path $ dest -Parent))){
New-Item $(Split-Path $ dest -Parent) - 类型目录
}

$ content = get-conte nt $ i

if($ content -ne $ null){

[System.IO.File] :: WriteAllLines($ dest,$ content,$ Utf8NoBomEncoding)
}
else {
写主机没有内容来自:$ i
}
}

现在每次迭代都会返回No content from:$ i消息,但文件不为空。还有一个错误: Get-content:找不到路径C:\root\FILENAME.php,因为它不存在。似乎它正在尝试在根目录下找到文件,而不是在子文件夹中。似乎能够从子文件夹获取文件名,但尝试从根目录读取。



编辑4 - 最终工作版本 / p>

经过一些挣扎,跟随我的建议,我来到这里,特别是从@LarsTruijens和@AnsgarWiechers,我终于做到了。我不得不改变从$ PWD获取目录的方式,并为文件夹设置一些固定名称。之后,它工作得很好。



对于任何可能感兴趣的人来说,

  $ Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($ False)
$ source =path
$ destination =some_folder

foreach($ i in Get-ChildItem -Recurse -Force){
if($ i.PSIsContainer){
continue
}

$ path = $ i。 DirectoryName -replace $ source,$ destination
$ name = $ i.Fullname -replace $ source,$ destination

if(!(Test-Path $ path)){
新项目-Path $ path -ItemType目录
}

$ content = get-content $ i.Fullname

if($ content -ne $ null) {

[System.IO.File] :: WriteAllLines($ name,$ content,$ Utf8NoBomEncoding)
} else {
写主机没有内容来自:$ i
}
}


解决方案

您没有按照此处。你忘记了WriteAllLines部分。

  $ Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($ False)
foreach ($ i Get-ChildItem -Recurse){
if($ i.PSIsContainer){
continue
}

$ dest = $ i.Fullname.Replace ($ PWD,some_folder)

if(!(Test-Path $(Split-Path $ dest -Parent))){
New-Item $(Split-Path $ dest -Parent目录
}

$ content = get-content $ i
[System.IO.File] :: WriteAllLines($ dest,$ content,$ Utf8NoBomEncoding )
}


I'm trying to do a dead simple thing: to change files encoding from anything to UTF-8 without BOM. I found several scripts that do this and the only one that really worked for me is this one: https://superuser.com/questions/397890/convert-text-files-recursively-to-utf-8-in-powershell#answer-397915.

It worked as expected, but I need the generated files without BOM. So I tried to modify the script a little, adding the solution given to this question: Using PowerShell to write a file in UTF-8 without the BOM

This is my final script:

foreach ($i in Get-ChildItem -Recurse) {
    if ($i.PSIsContainer) {
        continue
    }

    $dest = $i.Fullname.Replace($PWD, "some_folder")

    $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)

    if (!(Test-Path $(Split-Path $dest -Parent))) {
        New-Item $(Split-Path $dest -Parent) -type Directory
    }

    get-content $i | out-file -encoding $Utf8NoBomEncoding -filepath $dest
}

The problem is that powershell is returning me an error, regarding the System.Text.UTF8Encoding($False) line, complaining about an incorrect parameter:

It is not possible to validate the argument on the 'Encoding' parameter. The argument "System.Text.UTF8Encoding" dont belongs to the the group "unicode, utf7, utf8, utf32, ascii" specified by the ValidateSet attribute.

I wonder if I'm missing something, like powershell version or something like that. I never coded a Powershell script before, so I'm totally lost with this. And I need to change these files encoding, there are hundreds of them, I wouldn't like to do it myself one by one.

Actually I'm using the 2.0 version that comes with Windows 7.

Thanks in advance!

EDIT 1

I tried the following code, suggested by @LarsTruijens and other posts:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach ($i in Get-ChildItem -Recurse) {
    if ($i.PSIsContainer) {
        continue
    }

    $dest = $i.Fullname.Replace($PWD, "some_folder")

    if (!(Test-Path $(Split-Path $dest -Parent))) {
        New-Item $(Split-Path $dest -Parent) -type Directory
    }

    $content = get-content $i
    [System.IO.File]::WriteAllLines($dest, $content, $Utf8NoBomEncoding)
}

This gives me an Exception, complaining about one of the parameters for WriteAllLines: "Exception on calling 'WriteAllLines' with 3 arguments. The value can't be null". Parameter name: contents. The script creates all folders, though. But they are all empty.

EDIT 2

An interesting thing about this error is that the "content" parameter is not null. If I output the value of the $content variable (using Write-host) the lines are there. So why it becomes null when passed to WriteAllLines method?

EDIT 3

I've added a content check to the variable, so the script now looks like this:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach ($i in Get-ChildItem -Recurse) {
    if ($i.PSIsContainer) {
        continue
    }

    $dest = $i.Fullname.Replace($PWD, "some_folder")

    if (!(Test-Path $(Split-Path $dest -Parent))) {
        New-Item $(Split-Path $dest -Parent) -type Directory
    }

    $content = get-content $i

    if ( $content -ne $null ) {

        [System.IO.File]::WriteAllLines($dest, $content, $Utf8NoBomEncoding)
    }
    else {
        Write-Host "No content from: $i"
    }
}

Now every iteration returns "No content from: $i" message, but the file isn't empty. There is one more error: Get-content: can't find the path 'C:\root\FILENAME.php' because it doesn't exists. It seems that it is trying to find the files at the root directory and not in the subfolders. It appears to be able to get the filename from child folders, but tries to read it from root.

EDIT 4 - Final Working Version

After some struggling and following the advices I got here, specially from @LarsTruijens and @AnsgarWiechers, I finally made it. I had to change the way I was getting the directory from $PWD and set some fixed names for the folders. After that, it worked perfectly.

Here it goes, for anyone who might be interested:

    $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
    $source = "path"
    $destination = "some_folder"

    foreach ($i in Get-ChildItem -Recurse -Force) {
        if ($i.PSIsContainer) {
            continue
        }

        $path = $i.DirectoryName -replace $source, $destination
        $name = $i.Fullname -replace $source, $destination

        if ( !(Test-Path $path) ) {
            New-Item -Path $path -ItemType directory
        }

        $content = get-content $i.Fullname

        if ( $content -ne $null ) {

            [System.IO.File]::WriteAllLines($name, $content, $Utf8NoBomEncoding)
        } else {
            Write-Host "No content from: $i"   
        }
    }

解决方案

You didn't follow the whole answer in here. You forgot the WriteAllLines part.

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach ($i in Get-ChildItem -Recurse) {
    if ($i.PSIsContainer) {
        continue
    }

    $dest = $i.Fullname.Replace($PWD, "some_folder")

    if (!(Test-Path $(Split-Path $dest -Parent))) {
        New-Item $(Split-Path $dest -Parent) -type Directory
    }

    $content = get-content $i 
    [System.IO.File]::WriteAllLines($dest, $content, $Utf8NoBomEncoding)
}

这篇关于PowerShell - 批量更改文件编码为UTF-8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆