在大型(30G)单行文件上运行sed会返回空输出

时间:2017-06-09 20:00:30

标签: bash ubuntu sed command-line

我正在尝试使用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
    

我尝试过的事情

  • 在较短的文件上运行相同的示例:工作
  • 使用-e修饰符:不起作用
  • 逃避“&lt;”和“&gt;”:不起作用
  • 使用简单的图案线('s/foo/bar/g')代替:不起作用:返回零长度文件。

编辑(更多信息)

  • 返回代码 0

  • sed版本(GNU sed)4.2.2

4 个答案:

答案 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