替换大文件中包含换行符的字符串

替换大文件中包含换行符的字符串

有人知道基于非行的工具可以以某种节省内存的方式“二进制”搜索/替换字符串吗?这个问题也。

我有一个 +2GB 的文本文件,我想对其进行类似于以下操作的处理:

sed -e 's/>\n/>/g'

这意味着,我想删除 a 之后出现的所有换行符>,但不删除其他地方出现的换行符,这样就排除了tr -d.

这个命令(我从类似问题的答案) 失败并显示couldn't re-allocate memory

sed --unbuffered ':a;N;$!ba;s/>\n/>/g'

那么,除了C语言之外,还有其他方法吗?我讨厌 Perl,但我愿意在这种情况下破例:-)

我不确定数据中没有出现任何字符,因此\n如果可能的话,我想避免临时替换为另一个字符。

大家有什么好主意吗?

答案1

这在 Perl 中确实是微不足道的,你不应该讨厌它!

perl -i.bak -pe 's/>\n/>/' file

解释

  • -i:就地编辑文件,并创建原始文件的备份,称为file.bak.如果您不需要备份,只需使用perl -i -pe即可。
  • -pe:逐行读取输入文件并在应用给定的脚本后打印每一行-e
  • s/>\n/>/: 替换,就像sed.

这是一种awk方法:

awk  '{if(/>$/){printf "%s",$0}else{print}}' file2 

答案2

一个perl办法:

$ perl -pe 's/(?<=>)\n//'

说明

  • s///用于字符串替换。
  • (?<=>)是lookbehind模式。
  • \n匹配换行符。

整个模式意味着删除>之前的所有换行符。

答案3

这个怎么样:

sed ':loop
  />$/ { N
    s/\n//
    b loop
  }' file

对于 GNU sed,您还可以尝试根据问题添加-u( ) 选项。 --unbufferedGNU sed 也很高兴将此作为一个简单的单行代码:

sed ':loop />$/ { N; s/\n//; b loop }' file

答案4

sed不提供在没有最终换行符的情况下发出输出的方法。您使用的方法N从根本上有效,但在内存中存储不完整的行,因此如果行变得太长,则可能会失败(sed 实现通常不设计用于处理极长的行)。

您可以使用 awk 代替。

awk '{if (/<$/) printf "%s", $0; else print}'

另一种方法是使用tr“无聊”的频繁出现的字符来交换换行符。空格在这里可能起作用 - 选择一个往往出现在数据中的每一行或至少大部分行上的字符。

tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'

相关内容