因此,我有一个很大的文本文件文件夹,我想将每个文本文件中的字符串 unmed 更改为文件本身的名称,但不包括扩展名。
到目前为止,我已经运用以下技巧进行了总结,但是它并不能满足我的需求,因为它将名称更改为每个收集的文件
int*
基本上就是这样
此文件的名称未修改。
正在成为
此文件的名称为File1Name File2Name File3Name。
我遇到的另一个问题是所有文件的结果合并到一个文件中(因此文件1的内容现在也将包含所有其他文件的内容)。我如何获得我寻求的结果,哦,明智的选择?
如果有一种方法可以用常规命令行而不是powershell来解决,那么我也将解决(我发现了这一点,但是replace_string是无效命令吗?Batch script that replaces static string in file with filename)
答案 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)
从路径中提取文件名根(仅文件名不带扩展名)
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。