Linux に複数の小さなファイル (約 70,000 ファイル) があり、ファイルの各行の末尾に単語を追加して、それらをすべて 1 つのファイルにマージしたいと考えています。
私はこのスクリプトを使用しています:
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"
)
このソリューションには約かかりました。6秒。
ed
が標準のテキスト エディタであることを忘れないでください。あなたが楽しんだならed
、あなたもおそらく楽しむでしょうex
!
乾杯!
gniourf_gniourf のソリューションとほぼ同じですが、ed はありません。
for i in *.sms.txt
do
while read line
do
echo $line $i
done < $i
done >sms.txt
何、愛がないのawk
?
awk '{print $0" "FILENAME}' *.sms.txt >sms.txt
を使用すると、私のマシンの gniourf_gniourf のサンプルで1 ~ 2 秒gawk
かかりました (によると)。time
mawk
ここより約0.2秒速いgawk
です。
この perl スクリプトは、各行の末尾に実際のファイル名を追加します。
#!/usr/bin/perl
use strict;
while(<>){
chomp;
print $_, $ARGV, "\n";
}
次のように呼び出します。
scriptname *.sms.txt > sms.txt
プロセスが 1 つしかなく、正規表現処理が含まれていないため、非常に高速です。