Powershell Get -ChildItem:过滤CSV文件和-Recurse无法正常工作

时间:2019-05-30 19:06:23

标签: powershell

我创建了一个简短的powershell脚本,将csv文件从Unicode转换为UTF-8编码。我的脚本输出新文件,其原始文件名前面带有UTF8。我遇到了两个问题:

  1. 我正在尝试仅在csv文件上运行powershell脚本。当前,该脚本在目录中的每个文件上运行,包括powershell脚本(例如,如果将powershell脚本称为pshell_script,它将输出一个名为UTF8pshell_script的新文件)。我尝试仅在csv文件上运行脚本的其他方法最终会使脚本不执行任何操作。

  2. 我正在尝试在子目录上运行脚本。第一个问题是从子目录中的csv文件创建的输出文件内部没有任何内容。如果脚本在与csv文件相同的目录中运行,则不会出现此问题。这不是至关重要的,但我也不确定如何将子目录中的文件创建的输出文件输出到相同的子目录中(当前它们在powershell脚本所在的主目录中输出)。

    Get-Content -Encoding Unicode $_ | Out-File -Encoding UTF8
    Get-ChildItem -Recurse | ForEach-Object {Get-Content -Encoding Unicode $_ | Out-File -Encoding UTF8 "UTF8$_"}

所需的输出是仅在csv文件上运行的powershell脚本,并将文件输出到与创建它们的文件相同的子目录中。

4 个答案:

答案 0 :(得分:1)

function mapDispatchToProps(dispatch) { const actions = bindActionCreators({ searchSave }, dispatch); return { ...actions, dispatch }; } 带有一个Get-ChildItem参数,对于文件来说,它是简单的通配符模式。这将允许您将cmdlet限制为仅CSV文件:

-Filter

要处理子目录,您也可以使用Get-ChildItem -Filter *.csv 开关

-Recurse

现在,我不确定当您通过管道传递不同对象时Get-ChildItem -Filter *.csv -Recurse 会如何变化,因此我可能没有以最有效的方式进行下一步-但很明显,我正在尝试做:

我们找到的每个文件对象都需要进行如下处理:

  1. 将其分解为路径和文件名:$_
  2. 加载CSV:$filepath = $_.PSParentPath; $filename = $_.PSChildName
  3. 使用正确的编码输出新的CSV:Import-CSV -Path $_

因此,我们将所有内容放在一起:

Export-CSV -Path ("{0}\UTF8{1}" -f $filepath,$filename) -Encoding UTF8

Get-ChildItem -Filter *.csv -Recurse -exclude UTF8* | ForEach-Object { $filepath = $_.PSParentPath $filename = $_.PSChildName Import-CSV -Path $_ | Export-CSV -Encoding UTF8 -Path ("{0}\UTF8{1}" -f $filepath,$filename) -NoTypeInformation } 中的-Exclude UTF8*确保创建文件时不会在以后拾取该文件并对其进行重新处理。 Get-ChildItem上的-NoTypeInformation补偿了cmdlet内置的愚蠢行为,该愚蠢行为导致文件开头的多余行带有无意义的对象类型名称。

答案 1 :(得分:1)

根据原始编码(和BOM表的存在),您可能还必须在输入端指定一种编码。

ForEach($Csv in (Get-ChildItem -Filter *.csv -Recurse -Exclude UTF8*)){
  (Get-Content $Csv.FullName -raw) | 
    Set-Content -Path {Join-Path $Csv.Directory ("UTF8"+$Csv.Name)} -Encoding UTF8
}

答案 2 :(得分:1)

LotPings在几乎相同的答案下击败了我10分钟,但我将其保留为“将空文件传递到管道”位。我也意识到,出于同样的原因,您不需要管道变量,因为只有在循环中将内容通过管道传递时才需要它。

如果您只想更改编码,我将使用ForEach($x in $y){}循环,或ForEach-Object{}上带有PipelineVariable的{​​{1}}循环。我将说明这一点,因为我认为管道变量未得到充分利用。我也不会读取文件并将其通过管道传输到某些内容,因为如果文件为空,则不会创建新文件,因为没有任何东西沿管道传递。

Get-ChildItem

答案 3 :(得分:0)

如果您在Get-ChildItem的末尾指定文件扩展名。 这样只会获取扩展名为.csv的文件。

通过在Out-File中指定文件路径,会将其发送到指定目录。

Get-ChildItem -Path C:\folder\*.csv -Recurse | ForEach-Object {Get-Content -Encoding Unicode $_ | Out-File -FilePath C:\Folder -Encoding UTF8 "UTF8$_"}