我有多个小文件在Linux中(约70,000个文件),我想在每行的末尾添加一个单词,然后将它们全部合并成一个单一的文件。
我正在使用这个脚本:
for fn in *.sms.txt
do
sed 's/$/'$fn'/' $fn >> sms.txt
rm -f $fn
done
有更快的方法吗?
我用了这些文件:
for ((i=1;i<70000;++i)); do printf -v fn 'file%.5d.sms.txt' $i; echo -e "HAHA\nLOL\nBye" > "$fn"; done
我尝试了你的解决方案,处理时间大约为4分钟(实际)。你的解决方案存在问题,即你在sed
上进行了70000次分叉!而分叉速度相当慢。
#!/bin/bash
filename="sms.txt"
# Create file "$filename" or empty it if it already existed
> "$filename"
# Start editing with ed, the standard text editor
ed -s "$filename" < <(
# Go into insert mode:
echo i
# Loop through files
for fn in *.sms.txt; do
# Loop through lines of file "$fn"
while read l; do
# Insert line "$l" with "$fn" appended to
echo "$l$fn"
done < "$fn"
done
# Tell ed to quit insert mode (.), to save (w) and quit (q)
echo -e ".\nwq"
)
ed
是标准文本编辑器,请不要忽视它!如果你喜欢ed
,你可能也会喜欢ex
!for i in *.sms.txt
do
while read line
do
echo $line $i
done < $i
done >sms.txt
ed
似乎更快:您的解决方案花费了7秒钟!但是100%的bash解决方案值得大力点赞。 - gniourf_gniourf怎么没有人关注 awk
呢?
awk '{print $0" "FILENAME}' *.sms.txt >sms.txt
gawk
,在我的机器上(根据 time
),在 gniourf_gniourf 的 示例 上只需要 1-2 秒。mawk
比 gawk
快了约 0.2 秒。#!/usr/bin/perl
use strict;
while(<>){
chomp;
print $_, $ARGV, "\n";
}
这样调用:
scriptname *.sms.txt > sms.txt
由于只涉及一个进程且没有正则表达式处理,因此速度应该相当快。
gsed
过滤器,将它们从类似XML的格式转换为类似JSON的格式(不完全如此,但重要的是,它比这个问题需要的要复杂得多),花了大约2小时才完成。当然,它是在带有15000 RPM硬盘和8个CPU的机器上运行的,但仍然比我所希望的速度快得离谱。(请注意我说的是gsed
而不是sed
。OS X的sed
慢了两个数量级)。 - Pooria Azimi