我有一个文件users.txt
,其中包含
user1
user2
user3
我想在另一个文件data.txt
中找到这些单词并为其添加前缀。 data.txt
有近500K行。例如,user1
应替换为New_user1
,依此类推。我编写了简单的shell脚本,如
for user in `cat users.txt`
do
sed -i 's/'${user}'/New_&/' data.txt
done
对于大约1000个单词,这个程序需要花费几分钟来处理,这让我感到惊讶,因为sed在找到和替换时非常快。我试图引用Optimize shell script for multiple sed replacements,但仍未发现太多改善。
还有其他方法可以让这个过程更快吗?
答案 0 :(得分:2)
您可以将users.txt
变成这样的sed命令:
$ sed 's|.*|s/&/New_&/|' users.txt
s/user1/New_user1/
s/user2/New_user2/
s/user3/New_user3/
然后使用它来处理data.txt
,或者将上一个命令的输出写入中间文件,或者使用进程替换:
sed -f <(sed 's|.*|s/&/New_&/|' users.txt) data.txt
对于data.txt
中的每一行,您的方法都会经历所有users.txt
,这会使其变慢。
如果您不能使用流程替换,则可以使用
sed 's|.*|s/&/New_&/|' users.txt | sed -f - data.txt
代替。
答案 1 :(得分:2)
已知Sed非常快(可能只比C差)。
而不是sed 's/X/Y/g' input.txt
,请尝试sed '/X/ s/X/Y/g' input.txt
。众所周知后者更快。
由于您一次只有#34;一行语义&#34;,您可以使用parallel
(在多核cpu-s上)运行它,如下所示:
cat huge-file.txt | parallel --pipe sed -e '/xxx/ s/xxx/yyy/g'
如果您正在处理普通的ascii文件,可以使用&#34; C&#34;来加快速度。区域设置:
LC_ALL=C sed -i -e '/xxx/ s/xxx/yyy/g' huge-file.txt
答案 2 :(得分:1)
或者......一气呵成,我们可以做这样的事情。让我们说,我们有一个500k行的数据文件。
$>
wc -l data.txt
500001 data.txt
$>
ls -lrtha data.txt
-rw-rw-r--. 1 gaurav gaurav 16M Oct 5 00:25 data.txt
$>
head -2 data.txt ; echo ; tail -2 data.txt
0|This is a test file maybe
1|This is a test file maybe
499999|This is a test file maybe
500000|This is a test file maybe
我们假设我们的users.txt在文件“data.txt”中有3-4个关键字,前缀为“ab_”
$>
cat users.txt
file
maybe
test
因此我们想要阅读users.txt,对于每个单词,我们都希望将该单词更改为新单词。例如,“file”到“ab_file”,“maybe”到“ab_maybe”..
我们可以运行while循环,读取输入的单词逐个加前缀,然后我们在文件上运行perl命令,输入单词存储在变量中。在下面的示例中,read word作为$ word传递给perl命令。
我计划了这项任务,这很快发生了。它是否在我的VM上托管在我的Windows 10上(使用Centos7)。
time cat users.txt |while read word; do perl -pi -e "s/${word}/ab_${word}/g" data.txt; done
real 0m1.973s
user 0m1.846s
sys 0m0.127s
$>
head -2 data.txt ; echo ; tail -2 data.txt
0|This is a ab_test ab_file ab_maybe
1|This is a ab_test ab_file ab_maybe
499999|This is a ab_test ab_file ab_maybe
500000|This is a ab_test ab_file ab_maybe
在上面的代码中,我们读取了单词:test,file,maybe,并将其更改为data.txt文件中的ab_test,ab_file,ab_maybe。头尾数确认了我们的操作。
欢呼声, 拉夫