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

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

问题描述

我试图做一个死简单的事情:从什么改变文件编码为UTF-8无BOM。我发现了几个脚本,做到这一点,只有真正为我工作的一个是这一个:<一href=\"http://superuser.com/questions/397890/convert-text-files-recursively-to-utf-8-in-powershell#answer-397915\">http://superuser.com/questions/397890/convert-text-files-recursively-to-utf-8-in-powershell#answer-397915.

它的工作如预期,但我需要无BOM生成的文件。所以我试图修改剧本一点点,加上考虑到这个问题的解决方案:<一href=\"http://stackoverflow.com/questions/5596982/using-powershell-to-write-a-file-in-utf-8-without-the-bom/#answer-5596984\">Using PowerShell来编写UTF-8的文件没有BOM

这是我最后的脚本:

 的foreach($ i的GET-ChildItem -Recurse){
    如果($ i.PSIsContainer){
        继续
    }    $ DEST = $ i.Fullname.Replace($ PWDsome_folder)    $ Utf8NoBomEncoding =新对象System.Text.UTF8Encoding($假)    如果(!(测试的路径$(拆分路径$ DEST -Parent))){
        新建项目$(拆分路径$ DEST -Parent)型目录
    }    得到内容$ I |出文件-encoding $ Utf8NoBomEncoding -FilePath $ DEST
}

问题是,PowerShell是我返回一个错误,有关 System.Text.UTF8Encoding($假)行,抱怨不正确的参数:

这是不可能的验证上的编码参数的参数。参数System.Text.UTF8Encoding不要属于组UNI code,UTF7,UTF8,UTF32,ASCII由ValidateSet属性指定的。

我不知道如果我失去了一些东西,像PowerShell的版本或类似的东西。我以前PowerShell脚本从未$ C $的CD,所以我完全同意这个丢失。我需要更改这些文件的编码,也有数百人,我不希望被人做我自己的。

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

在此先感谢!

修改1

我尝试以下code,由@LarsTruijens和其他职位建议:

  $ Utf8NoBomEncoding =新对象System.Text.UTF8Encoding($假)
的foreach($ i的GET-ChildItem -Recurse){
    如果($ i.PSIsContainer){
        继续
    }    $ DEST = $ i.Fullname.Replace($ PWDsome_folder)    如果(!(测试的路径$(拆分路径$ DEST -Parent))){
        新建项目$(拆分路径$ DEST -Parent)型目录
    }    $内容=获取内容$ I
    [有System.IO.File] :: WriteAllLines($ DEST,$内容,$ Utf8NoBomEncoding)
}

这给了我一个异常,抱怨为WriteAllLines的参数之一:在异常调用WriteAllLines与3个参数的值不能为空。参数名:内容。该脚本创建的所有文件夹,但。但它们都是空的。

编辑2

有关此错误的一个有趣的事情是,内容参数不为null。如果我输出$内容变量的值(用写主机)线的存在。那么,为什么传递给WriteAllLines方法,当它变成空?

编辑3

我添加了一个内容检查的变量,因此脚本现在看起来是这样的:

  $ Utf8NoBomEncoding =新对象System.Text.UTF8Encoding($假)
的foreach($ i的GET-ChildItem -Recurse){
    如果($ i.PSIsContainer){
        继续
    }    $ DEST = $ i.Fullname.Replace($ PWDsome_folder)    如果(!(测试的路径$(拆分路径$ DEST -Parent))){
        新建项目$(拆分路径$ DEST -Parent)型目录
    }    $内容=获取内容$ I    如果($内容-ne $ NULL){        [有System.IO.File] :: WriteAllLines($ DEST,$内容,$ Utf8NoBomEncoding)
    }
    其他{
        写主机,从没有的内容:$ I
    }
}

现在每次迭代返回从没有的内容:$ I的消息,但该文件不为空。还有一个错误:获取内容:找不到路径。C:\\ ROOT \\ FILENAME.php,因为不存在,它它似乎试图找到根目录和子文件夹中的文件没有。这似乎是能够从子文件夹的文件名,但试图从根读取。

修改4 - 最后的工作版本

经过一番挣扎,下面我来到这里,特地从@LarsTruijens和@AnsgarWiechers的建议,我终于做到了。我不得不改变我正在从$ PWD目录的方式和文件夹设置一些固定名称。之后,它完美地工作。

这里有云,人谁可能感兴趣的:

  $ Utf8NoBomEncoding =新对象System.Text.UTF8Encoding($假)
    $源=路径
    $目标=some_folder    的foreach($ i的GET-ChildItem -Force -Recurse){
        如果($ i.PSIsContainer){
            继续
        }        $ PATH = $ i.DirectoryName -replace $源,目标$
        $ NAME = $ i.Fullname -replace $源,目标$        如果(!(测试的路径$路径)){
            新建项目-Path $ PATH -ItemType目录
        }        $内容=获取内容$ i.Fullname        如果($内容-ne $ NULL){            [有System.IO.File] :: WriteAllLines($名称,$内容,$ Utf8NoBomEncoding)
        }其他{
            写主机,从没有的内容:$ I
        }
    }


解决方案

您没有按照整个答案<一个href=\"http://stackoverflow.com/questions/5596982/using-powershell-to-write-a-file-in-utf-8-without-the-bom/#answer-5596984\">here.你忘了WriteAllLines一部分。

  $ Utf8NoBomEncoding =新对象System.Text.UTF8Encoding($假)
的foreach($ i的GET-ChildItem -Recurse){
    如果($ i.PSIsContainer){
        继续
    }    $ DEST = $ i.Fullname.Replace($ PWDsome_folder)    如果(!(测试的路径$(拆分路径$ DEST -Parent))){
        新建项目$(拆分路径$ DEST -Parent)型目录
    }    $内容=获取内容$ I
    [有System.IO.File] :: WriteAllLines($ DEST,$内容,$ 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: http://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天全站免登陆