我正在尝试使用sed
在大型(30G)单行文件上执行简单的文字搜索/替换。
我希望这需要一些时间但是,当我运行它时,它会在几秒后返回,当我查看生成的文件时,它的长度为零。
输入文件有30G
$ ls -lha Full-Text-Tokenized-Single-Line.txt
-rw-rw-r-- 1 ubuntu ubuntu 30G Jun 9 19:51 Full-Text-Tokenized-Single-Line.txt
运行命令:
$ sed 's/<unk>/ /g' Full-Text-Tokenized-Single-Line.txt > Full-Text-Tokenized-Single-Line-No-unks.txt
输出文件的长度为零!
$ ls -lha Full-Text-Tokenized-Single-Line-No-unks.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Jun 9 19:52 Full-Text-Tokenized-Single-Line-No-unks.txt
我尝试过的事情
's/foo/bar/g'
)代替:不起作用:返回零长度文件。返回代码 0
sed版本(GNU sed)4.2.2
答案 0 :(得分:4)
只需使用awk,它就是为处理由任意字符串分隔的记录而设计的。使用GNU awk进行多字符RS:
awk -v RS='<unk>' '{ORS=(RT?" ":"")}1' file
上面将输入拆分为由<unk>
分隔的记录,因此如果输入中存在足够的<unk>
s,则各个记录将足够小以适合内存。然后打印每个记录后跟一个空白字符,这样对数据的总体影响就是所有<unk>
成为空白字符。
如果这种直接方法对您不起作用,那么就该开始寻找其他解决方案了。
答案 1 :(得分:3)
使用基于行的编辑器,例如sed
,您不能指望它能够正常工作,因为它的工作单元(记录)是以换行符结束的行。
如果您的文件中有空格(以防止搜索模式被拆分),请使用
fold -s file_with_one_long_line |
sed 's/find/replace/g' |
tr -d '\n' > output
ps。 fold
默认宽度为80,如果您的文字长于80,则可以添加-w 1000
或至少最长的字大小以防止分词。
答案 2 :(得分:2)
官方gnu sed没有行限制 http://www.linuxtopia.org/online_books/linux_tool_guides/the_sed_faq/sedfaq6_005.html 但是页面说明:
&#34;没有限制&#34;意味着没有&#34;固定&#34;限制。限制实际上由一个硬件,内存,操作系统以及用于编译sed的C库决定。
我尝试在7gb单个文件上运行sed可以重现同样的问题。 此页https://community.hpe.com/t5/Languages-and-Scripting/Sed-Maximum-Line-Length/td-p/5136721建议使用perl
perl -pe 's/start=//g;s/stop=//g;s/<unk>/ /g' file > output
答案 3 :(得分:2)
如果标记是空格(不是所有空格)分隔并假设您只匹配单个单词,那么您可以使用perl with space作为记录分隔符
perl -040 -pe 's/<unk>/ /' file
或GNU awk匹配所有空格
awk -vRS="[[:space:]]" '{ORS=RT;sub(/<unk>/," ")} file