在大型文件中查找和替换

Raj*_*j73 6 powershell

我想在大型xml文件中找到一段文本,并希望替换为其他一些文本.文件大小约为(50GB).我想在命令行中执行此操作.我正在看Powershell并想知道它是否可以处理大尺寸.另外我想知道在PowerShell中转义关键运算符的语法.我是PowerShell的新手

目前我正在尝试这样的事情,但它不喜欢它

    Get-Content C:\File1.xml | Foreach-Object {$_ -replace "xmlns:xsi=\"http:\/\/www\.w3\.org\/2001\/XMLSchema-instance\"", ""} | Set-Content C:\File1.xml
Run Code Online (Sandbox Code Playgroud)

我要替换的文本是 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance",带有空字符串"".

问题

  1. powerShell可以处理大文件吗?
  2. 如何从命令行调用powershell脚本
  3. 在powerShell中转义键运算符的语法和powerShell中的关键运算符列表.
  4. 我不希望替换发生在内存中,并且更喜欢流式传输,假设不会让服务器瘫痪.
  5. 我还有其他方法吗(不同的工具/策略?)

谢谢

Dig*_*ote 13

除了担心分块读取文件以避免将其加载到内存中之外,您还需要足够频繁地转储到磁盘,以免将结果文件的全部内容存储在内存中。

Get-Content sourcefile.txt -ReadCount 10000 | 
    Foreach-Object {
        $line = $_.Replace('http://example.com', 'http://another.example.com')
        Add-Content -Path result.txt -Value $line
    }
Run Code Online (Sandbox Code Playgroud)

设置-ReadCount <number>一次读取的行数。然后ForEach-Object在读取时写入每一行。对于充满 SQL 插入的 30GB 文件,我使用了大约 200MB 的内存和 8% 的 CPU。同时,Set-Content在我杀死它之前,将其全部传输到 3GB 内存中。


Rob*_*lan 11

我有类似的需求(和类似的缺乏PowerShell体验),但拼凑了这个页面上的其他答案的完整答案加上更多的研究.

我也想避免正则表达式处理,因为我也不需要它 - 只是一个简单的字符串替换 - 但是在一个大文件上,所以我不希望它加载到内存中.

这是我使用的命令(添加换行符以提高可读性):

Get-Content sourcefile.txt
    | Foreach-Object {$_.Replace('http://example.com', 'http://another.example.com')}
    | Set-Content result.txt
Run Code Online (Sandbox Code Playgroud)

工作得很完美!从来没有吸过太多内存(显然没有将整个文件加载到内存中),只是匆匆忙忙几分钟然后就完成了.


Kei*_*ill 4

它不喜欢它,因为您无法使用 Get-Content/Set-Content 同时读取文件并写回文件。我建议使用临时文件,然后最后将 file1.xml 重命名为 file1.xml.bak,并将临时文件重命名为 file1.xml。

  1. 是的,只要您不尝试一次加载整个文件即可。逐行可以工作,但会有点慢。使用 -ReadCount 参数并将其设置为 1000 以提高性能。
  2. 哪个命令行?电源外壳?如果是这样,那么您可以像这样调用脚本,.\myscript.ps1如果它需要参数,那么c:\users\joe\myscript.ps1 c:\temp\file1.xml
  3. 一般来说,对于正则表达式,如果您不需要引用 PowerShell 变量,我会使用单引号。那么你只需要担心正则表达式转义,而不用担心 PowerShell 转义。如果需要使用双引号,则反引号字符是双引号中的转义字符,例如“`$p1 is set to $ps1”。在您的示例中,单引号将您的正则表达式简化为(注意:正斜杠不是正则表达式中的元字符):

    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'

  4. 你绝对想流式传输它,因为 50GB 的内存装不下。但是,如果逐行处理,这会带来问题。如果您要替换的文本分为多行怎么办?

  5. 如果您没有分割线问题,那么我认为 PowerShell 可以处理这个问题。