首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在大型搜索/替换操作中,PowerShell速度很慢(比Python慢得多)?

在大型搜索/替换操作中,PowerShell速度很慢(比Python慢得多)?
EN

Stack Overflow用户
提问于 2012-03-16 00:58:58
回答 4查看 14.5K关注 0票数 20

我有265个CSV文件,总共超过400万条记录(行),需要在所有CSV文件中进行搜索和替换。下面是我的PowerShell代码片段,它可以做到这一点,但它需要17分钟来执行该操作:

代码语言:javascript
运行
复制
ForEach ($file in Get-ChildItem C:\temp\csv\*.csv) 
{
    $content = Get-Content -path $file
    $content | foreach {$_ -replace $SearchStr, $ReplaceStr} | Set-Content $file
}

现在我有了下面的Python代码,它可以做同样的事情,但只需要不到1分钟的时间:

代码语言:javascript
运行
复制
import os, fnmatch

def findReplace(directory, find, replace, filePattern):
    for path, dirs, files in os.walk(os.path.abspath(directory)):
        for filename in fnmatch.filter(files, filePattern):
            filepath = os.path.join(path, filename)
            with open(filepath) as f:
                s = f.read()
            s = s.replace(find, replace)
            with open(filepath, "w") as f:
                f.write(s)

findReplace("c:/temp/csv", "Search String", "Replace String", "*.csv")

为什么Python方法要高效得多?是我的PowerShell代码效率低下,还是在文本操作方面,Python只是一种功能更强大的编程语言?

EN

回答 4

Stack Overflow用户

发布于 2012-03-16 01:07:42

试一下这个PowerShell脚本。它应该表现得更好。RAM的使用也要少得多,因为文件是在缓冲流中读取的。

代码语言:javascript
运行
复制
$reader = [IO.File]::OpenText("C:\input.csv")
$writer = New-Object System.IO.StreamWriter("C:\output.csv")

while ($reader.Peek() -ge 0) {
    $line = $reader.ReadLine()
    $line2 = $line -replace $SearchStr, $ReplaceStr
    $writer.writeline($line2)
}

$reader.Close()
$writer.Close()

这将处理一个文件,但您可以使用它测试性能,如果它更容易接受,则将其添加到循环中。

或者,您可以使用Get-Content将许多行读取到内存中,执行替换,然后利用PowerShell管道写入更新后的块。

代码语言:javascript
运行
复制
Get-Content "C:\input.csv" -ReadCount 512 | % {
    $_ -replace $SearchStr, $ReplaceStr
} | Set-Content "C:\output.csv"

要获得更高的性能,您还可以编译正则表达式(-replace使用正则表达式),如下所示:

代码语言:javascript
运行
复制
$re = New-Object Regex $SearchStr, 'Compiled'
$re.Replace( $_ , $ReplaceStr )
票数 10
EN

Stack Overflow用户

发布于 2012-03-16 01:37:51

我经常看到这样的情况:

代码语言:javascript
运行
复制
$content | foreach {$_ -replace $SearchStr, $ReplaceStr} 

-replace运算符将一次处理整个数组:

代码语言:javascript
运行
复制
$content -replace $SearchStr, $ReplaceStr

而且比一次迭代一个元素要快得多。我怀疑这样做可能会让你更接近苹果与苹果的比较。

票数 7
EN

Stack Overflow用户

发布于 2012-10-05 12:41:47

您可能希望尝试以下命令:

代码语言:javascript
运行
复制
gci C:\temp\csv\*.csv | % { (gc $_) -replace $SearchStr, $ReplaceStr | out-file $_}

此外,一些字符串可能需要转义字符,因此您应该使用regexEscape生成内置转义字符的字符串。代码将如下所示:

代码语言:javascript
运行
复制
gci C:\temp\csv\*.csv | % { (gc $_) -replace $([regex]::Escape($SearchStr)) $([regex]::Escape($ReplaceStr)) | out-file $_}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9724521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档