2010-05-06 114 views
5

我想在一个大型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 

我要替换的文字是的xmlns:XSI =“HTTP://www.w3。 org/2001/XMLSchema-instance“ with empty string”“。

问题

  1. 灿PowerShell中处理大量 文件
  2. 如何调用 PowerShell脚本的命令行
  3. 转义键 运营商在PowerShell和主要运营商的列表 的语法在PowerShell中。
  4. 我不希望替换发生在 内存和更喜欢流假设 ,这将不会使服务器到它的膝盖 。
  5. 有没有我可以采取任何其他方式(不同 工具/策略?)

感谢

回答

3

它不喜欢它,因为你不能从文件中读取,并在写回它同时使用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被设置为$ ps1”。在你的例子中,单引号简化了你的正则表达式(注意:正斜杠不是正则表达式中的元字符):

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

  4. 绝对你想流这个,因为50GB不适合内存。但是,如果您逐行处理,则会出现问题。如果要替换的文本分成多行,该怎么办?

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

@Keith,您相信PowerShell中)我想也许担心OutOfMemoryException,因为50gb足够大以收集少量内存泄漏。只是一个猜测。就个人而言,我会直接使用'File.Open'并使用流并手动比较(无正则表达式)。 – stej 2010-05-06 20:41:09

+0

而不应该使用某种XML API来执行此操作吗?只是一个想法。如果SAX或StAX在.NET中可用,则不知道;我对XML的工作很少,但是做一个字符串替换听起来不对。 – Joey 2010-05-06 21:08:39

+0

.NET有一个只向前的游标式阅读器(XmlReader/XmlTextReader) - 一种与SAX推入方法有点不同的拉机制。这有点乏味,但是当整个Xml文档不适合内存时,这是一个好方法。 – 2010-05-07 04:04:44

-1

PowerShell字符串中的转义字符是反引号(`),而不是反斜线(\)。我举一个例子,但反标签也被wiki标记使用。 :(

你应该有逃脱的唯一事情是引号 - 周期和这样应该没有罚款

9

我也有类似的需求(以及类似的缺乏经验的PowerShell),但是拼凑起来的一个完整的答案从这个页面上的其他答案加上更多的研究

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

下面是我使用的命令(为可读性添加换行符):

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

工作完美!从来没有吸收过多的内存(很明显,它没有将整个文件加载到内存中),只需要几分钟就可以完成。

+0

PS花了3.5 GB的RAM。 30%的CPU当我杀了它。 – Tilo 2017-03-22 22:02:28

+0

也许检查** - ReadCount **或** - RAW ** http://www.happysysadm.com/2014/10/reading-large-text-files-with-powershell.html – Tilo 2017-03-22 22:07:12

0

这是我对了,建立在一些其他的答案在这里:

Function ReplaceTextIn-File{ 
    Param(
    $infile, 
    $outfile, 
    $find, 
    $replace 
) 

    if(-Not $outfile) 
    { 
    $outfile = $infile 
    } 

    $temp_out_file = "$outfile.temp" 

    Get-Content $infile | Foreach-Object {$_.Replace($find, $replace)} | Set-Content $temp_out_file 

    if(Test-Path $outfile) 
    { 
    Remove-Item $outfile 
    } 

    Move-Item $temp_out_file $outfile 
} 

并称为像这样:

ReplaceTextIn-File -infile "c:\input.txt" -find 'http://example.com' -replace 'http://another.example.com'