有人知道基于非行的工具可以以某种节省内存的方式“二进制”搜索/替换字符串吗?看这个问题也。
我有一个 +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
( ) 选项。 --unbuffered
GNU 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'