用文件名替换多个文件中的字符串

时间:2018-09-30 01:09:45

标签: powershell cmd

因此,我有一个很大的文本文件文件夹,我想将每个文本文件中的字符串 unmed 更改为文件本身的名称,但不包括扩展名。

到目前为止,我已经运用以下技巧进行了总结,但是它并不能满足我的需求,因为它将名称更改为每个收集的文件

int*

基本上就是这样

  

此文件的名称未修改。

正在成为

  

此文件的名称为File1Name File2Name File3Name。

我遇到的另一个问题是所有文件的结果合并到一个文件中(因此文件1的内容现在也将包含所有其他文件的内容)。我如何获得我寻求的结果,哦,明智的选择?

如果有一种方法可以用常规命令行而不是powershell来解决,那么我也将解决(我发现了这一点,但是replace_string是无效命令吗?Batch script that replaces static string in file with filename

2 个答案:

答案 0 :(得分:1)

像这样吗?

Get-ChildItem -Filter "*.txt" | ForEach-Object {
  $Path=$_.FullName; (Get-Content $Path) -replace 'unamed', $_.BaseName | Set-Content $Path 
}

答案 1 :(得分:0)

Esperanto's answer works well,并且与PSv2兼容;这是一个更快-但需要更多内存的PSv3 +解决方案:

Get-Content -Raw *.txt | ForEach-Object {
  $_ -replace 'unamed', [IO.Path]::GetFileNameWithoutExtension($_.PSPath) |
    Set-Content $_.PSPath
}
  • 除非您有特殊的文件匹配需求,例如递归查找文件,需要排除文件或需要按文件属性进行匹配,否则不需要Get-Item / Get-ChildItem来枚举感兴趣的文件-您可以将*.txt之类的通配符模式直接传递给Get-Content的(暗示)-Path参数。

  • Get-Content -Raw(PSv3 +)将与*.txt匹配的每个文件的全部内容作为一个单个字符串读取到整个存储器 中。 em>。

    • 注意:因为每个文件在输出到管道之前都需要整体读取,所以此解决方案可能无法处理非常大的文件,具体取决于可用内存。
  • Get-Content用有关字符串来源的信息修饰输出的字符串,以便每个返回的字符串的.PSPath属性包含读取该字符串的文件的完整文件名来自。

  • [IO.Path]::GetFileNameWithoutExtension($_.PSPath)从路径中提取文件名根(仅文件名不带扩展名)

    • 必须直接使用.NET,不幸的是,Split-Path cmdlet不允许您在Windows PowerShell中执行此操作,但是在PowerShell Core 中,您可以使用{{1 }}。

注意事项Split-Path -LeafBase使用默认编码(Windows PowerShell:“ ANSI”; PowerShell Core :UTF-8,不包含BOM),它可能与输入编码相同或不同;根据需要使用Set-Content参数。


关于您尝试过的事情

  

-Encoding

$filename = Get-Item $path | Select-Object -ExpandProperty BaseName现在包含文件名根(基本名称)的数组

  

$filename

$Change = Get-Content $path现在包含一个单个数组,其元素是来自所有输入文件的行

  

$Change

  • 由于$Change | ForEach-Object {$_ -Replace "unamed", $filename} | Set-Content $path是单个平面数组,因此您已经失去了将数组元素划分到文件或源中的功能,并且$Change发送 all 行到目标文件。

  • 因为Set-Content是一个 array ,而$filename的第二个RHS操作数仅支持 scalar (单个字符串),{ {1}}使-replace转换为单个字符串,该字符串是数组元素(文件名根)的以空格分隔的串联

  • $_ -replace "unamed", $filename碰巧将平面(修改后的)行数组写入多个文件,即与$filename中的通配符表达式匹配的现有文件, Set-Content $Path

    • 如上所述,输入$Path收到的是输入文件行的串联,因此所有输出文件都从 all接收串联(修改)的内容输入文件(名称与通配符模式*.txt匹配的所有文件)

    • 顺便说一句:Set-Content允许将相同内容写入到多个预先存在的输出文件中,这是一个令人惊讶且可能具有破坏性的功能,应该争论不休。不支持-请参见this GitHub discussion