
600万を超えるレコードを含む2つの大きなファイルがあります。これら2つのファイルのデータは、次のように関連付けることができます。ユーザーID(ファイルを注文する場合は、2つのファイルが同じ行になければなりません。)最終的に、2番目のファイルのデータに関連付けられている最初のファイルのデータをインポートする必要があります。
問題は、スクリプトを実行すると約650,000レコードを処理するのに10時間かかることです。
私はそれを改善したい。
UIDS=`cut -f1 -d',' sorted_UID_data1.txt`
for record in $UIDS
do
echo `grep $record sorted_UID_data1.txt| awk -F ',' '{print $2}'`,`grep $record sorted_UID_data2.txt` >> data.txt
done
それを最適化するために私は考えました。
TOTAL_RECORDS=`wc -l < sorted_UID_data1.txt`
recordId=1
while [ $recordId -le $TOTAL_RECORDS ]
do
echo `sed -n "${recordId}{p;q;}" sorted_UID_data1.txt| awk -F ',' '{print $2}'`,`sed -n "${recordId}{p;q;}" sorted_UID_data2.txt` >> data.txt
recordId=$(( $recordId + 1 ))
done
時間もかかりすぎました。
しかし、その時私は考えました。常にファイルの最初の行をキャッチできるとしたらどうでしょうか?私はこれを次のように行うことができることを見ました。sed、尾またはAWKしかし、これは非効率的なようです。
この問題をどのように解決できますか?
答え1
最初の行を削除するには、次のようにしますtail
。
# seq 5 | tail -n +2
2
3
4
5
「最初の行をインポートするには」以下のみを使用してくださいhead
。
# seq 5 | head -n 1
1
ただし、2つのファイルを1行ずつリンクするには、次のようにしますpaste
。
# seq 5 > nums
# echo -e 'a\nb\nc\nd\ne' > chars
# paste nums chars
1 a
2 b
3 c
4 d
5 e
一致する共通ファイルに2つのファイルを結合するには、次のようにしますjoin
。
# paste -d , <( seq 5 ) <( seq 11 15 ) > teens
# paste -d , <( seq 5 ) <( seq 21 25 ) > twenties
# join -t , teens twenties
1,11,21
2,12,22
3,13,23
4,14,24
5,15,25
答え2
キーフィールドを使用する場合は、次を使用することをお勧めします。参加する
join -t ',' sorted_UID_data1.txt sorted_UID_data2.txt