2016-08-18 78 views
0

我有一个很大的文本文件(大约10GB),它适合内存没有任何问题。我的目标是将每一行转换为base64字符串。目前我的方法需要永久,因为它是单线程的,似乎并不完整。Base64编码逐行更快的方式

while read line; do echo -n -i $line | base64 >> outputfile.txt; done < inputfile.txt 

有人能给我一个提示如何更快地做到这一点吗?此解决方案每小时创建大约100MB(因此修整时间为100小时),CPU使用率为5%,磁盘使用率也非常低。

看来我得到了missunderstood有关控制字符... 所以,我包括示例文本文件,输出应该如何(chepner是与格格正确):

样品输入:

Банд`Эрос 
testè!?£$ 
`` 
▒``▒` 

样本输出:

[email protected] ~ # head -n 5 bash-script-output.txt 
0JHQsNC90LRg0K3RgNC+0YE= 
dGVzdMOoIT/CoyQ= 
YGA= 
4paSYGDilpJg 

[email protected] ~ # head -n 5 perl-without-chomp.txt 
0JHQsNC90LRg0K3RgNC+0YEK 
dGVzdMOoIT/CoyQK 
YGAK 
4paSYGDilpJgCg== 

[email protected] ~ # head -n 5 perl-chomp.txt 
0JHQsNC90LRg0K3RgNC+0YE= 
dGVzdMOoIT/CoyQ= 
YGA= 
4paSYGDilpJg 

So样本是每次更好然后人类声明; =)

+1

echo的哪个版本支持'-i'选项? – chepner

+0

默认情况下,'base64'将换行符插入长编码行中;你可能想通过使用'-w0'选项来避免这种情况。如果您的输入文件包含NUL(这意味着它不是一个真正的文本文件),那么它们将不会通过读入shell变量来保存。 – rici

回答

2

它可以帮助一点点地打开输出文件只有一次:

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 
+0

我正在使用echo -n -i(我忽略/隐藏不可打印的字符,换行符为n)...我无法在$ _中适用它,所以你的编码不​​考虑这一点。但它非常快,大约200MB/5秒。 – snapo

+0

perl行与运行'base64 outputfile.txt'相同 - 但不会像逐行读取输入一样产生相同的输出(不同之处在于新行保留在慢速版中)。 – gilez

+0

@gilez不,它不是;输入文件的每一行都被分别编码和打印。 – chepner