我有一个大文本文件(大约10GB),它可以毫不费力地存储到内存中。我的目标是将每一行转换为base64字符串。目前我的方法需要永远,似乎没有完成,因为它是单线程的。
while read line; do echo -n -i $line | base64 >> outputfile.txt; done < inputfile.txt
有人可以给我一个如何更快地提示吗?这个解决方案每小时产生大约100MB(因此整理时间为100h)CPU使用率为5%,磁盘使用率也非常低。
似乎我误解了控制角色...... 所以我包含了一个示例文本文件,以及输出应该是什么(chepner在chomp中是正确的):
示例输入:
Банд`Эрос
testè!?£$
``
▒``▒`
示例输出:
user@monster ~ # head -n 5 bash-script-output.txt
0JHQsNC90LRg0K3RgNC+0YE=
dGVzdMOoIT/CoyQ=
YGA=
4paSYGDilpJg
user@monster ~ # head -n 5 perl-without-chomp.txt
0JHQsNC90LRg0K3RgNC+0YEK
dGVzdMOoIT/CoyQK
YGAK
4paSYGDilpJgCg==
user@monster ~ # head -n 5 perl-chomp.txt
0JHQsNC90LRg0K3RgNC+0YE=
dGVzdMOoIT/CoyQ=
YGA=
4paSYGDilpJg
所以样本每次都比人类声明更好; =)
答案 0 :(得分:3)
仅打开一次输出文件可能会有所帮助:
while IFS= read -r line; do echo -n $line | base64; done < inputfile.txt > outputfile.txt
bash
在这里不是一个好选择,但有两个原因:迭代文件的开始很慢,并且您为每一行开始一个新进程。更好的想法是使用具有用于计算base64值的库的语言,以便在一个进程中处理所有内容。使用Perl的示例
perl -MMIME::Base64 -ne 'print encode_base64($_)' inputfile.txt > outputfile.txt
答案 1 :(得分:0)
不要使用perl或任何其他dyn类型的语言来处理10G文本,尤其是在以下情况下:受串行处理的约束,期望源有效载荷随时间增加和/或在处理时间附近具有一些SLA。
如果顺序无关紧要,那么一定要绕过高级语言方法,因为您可以使用shell和posix组件免费并行处理。
$ printf "%s\n" one two three
one
two
three
$ printf "%s\n" one two three \
> | xargs \
> -P3 `# three parallel processes` \
> -L1 `# use one line from stdin` \
> -- sh -c 'echo $@ | base64' _
b25lCg==
dHdvCg==
dGhyZWUK
即使顺序(读取,处理,写入)受约束,我仍然会利用可用的多个内核,将工作分散到多个处理程序,然后分散到一些类似reducer的方法,单一过程。
# add line number to each line
$ printf "%s\n" one two three | nl
1 one
2 two
3 three
# base64 encode second column
$ printf "%s\n" one two three \
> | nl \
> | xargs -P3 -L1 sh -c \
> 'echo $2 | base64 | xargs printf "%s %s\n" "$1"' _
2 dHdvCg==
1 b25lCg==
3 dGhyZWUK
# sort based on numeric value of first col
$ printf "%s\n" one two three \
> | nl \
> | xargs -P3 -L1 sh -c \
> 'echo $2 | base64 | xargs printf "%s %s\n" "$1"' _ \
> | sort -k1 -n
1 b25lCg==
2 dHdvCg==
3 dGhyZWUK
所有这些方法都将扩展到可用核心的数量,并且所有繁重的工作(在文本处理方面)都是由古老的c二进制文件完成的,它将胜过其他任何事情。
如果您是一个狂想者,请使用C来完成整个工作,但是我可以保证以上内容将胜过用perl,python,ruby等编写的任何内容。内核将管理管道之间的缓冲区,这意味着大部分深奥的工作已经完成。