我有一个创建脚本的任务,它将一个巨大的文本文件作为输入。然后需要查找所有单词和出现次数,并创建一个新文件,每行显示一个唯一的单词及其出现次数。是否有可能使这个shell脚本更快?
举个例子取文件与此内容:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
我需要创建一个文件,该文件是这样的:
1 AD
1 ADIPISICING
1 ALIQUA
...
1 ALIQUIP
1 DO
2 DOLOR
2 DOLORE
...
为此,我使用tr
,sort
写了一个剧本, uniq
:
#!/bin/sh
INPUT=$1
OUTPUT=$2
if [ -a $INPUT ]
then
tr '[:space:][\-_?!.;\:]' '\n' < $INPUT |
tr -d '[:punct:][:special:][:digit:]' |
tr '[:lower:]' '[:upper:]' |
sort |
uniq -c > $OUTPUT
fi
这是干什么的es将空格分隔为分隔符。如果这个词包含-_?!.;:
我将它们再次分解成单词。我删除了标点,特殊字符和数字,并将整个字符串转换为大写。一旦完成,我将它分类并通过uniq
传递给我想要的格式。
现在我下载了TXT格式的圣经,并用它作为输入。时序本我:
scripts|$ time ./text-to-word.sh text.txt b
./text-to-word.sh text.txt b 16.17s user 0.09s system 102% cpu 15.934 total
我做了一个Python脚本一样:
import re
from collections import Counter
from itertools import chain
import sys
file = open(sys.argv[1])
c = Counter()
for line in file.readlines():
c.update([re.sub('[^a-zA-Z]', '', l).upper()
for l in chain(*[re.split('[-_?!.;:]', word)
for word in line.split()])])
file2 = open('output.txt', 'w')
for key in sorted(c):
file2.write(key + ' ' + str(c[key]) + '\n')
当我执行我拿到剧本:
scripts|$ time python text-to-word.py text.txt
python text-to-word.py text.txt 7.23s user 0.04s system 97% cpu 7.456 total
正如你可以看到它跑7.23s相比,在16.17s运行的shell脚本。我已经尝试过更大的文件,并且总是Python似乎取得了胜利。我对上面的senario有几个问题:
- 为什么Python脚本更快,因为shell命令是用C编写的?我意识到shell脚本可能不是最佳的脚本。
- 我该如何改进shell脚本?
- 我可以改进Python脚本吗?
要清楚我没有比较Python shell脚本。我并非试图开始一场火焰战争,或者不需要任何其他语言的答案来比较自己的速度。使用管道小命令执行任务的UNIX哲学,我如何更快地创建shell脚本?
我建议标题更改为类似“是否有可能使这个shell脚本更快?“,使用如此不同的python脚本onl y作为比较点。这将消除python和shell之间无用的和无关主题讨论的风险。 – 2012-08-16 13:11:19
我不认为使用很多小命令很好地完成单个任务的\ nix理念已经到位,因为它是最高效的*。它的原因是因为使用我们的工具,您可以完成如此多的任务,为您的简单任务节省大量时间开发新程序。 – mgilson 2012-08-16 13:26:31
Python也是用C编写的。 “用C写成”不足以让事情变得更快 - 插入层(以及所有读写流水线和管线)都有开销。 – 2012-08-16 14:15:55