4

Linux に複数の小さなファイル (約 70,000 ファイル) があり、ファイルの各行の末尾に単語を追加して、それらをすべて 1 つのファイルにマージしたいと考えています。

私はこのスクリプトを使用しています:

for fn in *.sms.txt 
do 
    sed 's/$/'$fn'/' $fn >> sms.txt
    rm -f $fn
done

これを行うより速い方法はありますか?

4

4 に答える 4

6

これらのファイルで試しました:

for ((i=1;i<70000;++i)); do printf -v fn 'file%.5d.sms.txt' $i; echo -e "HAHA\nLOL\nBye" > "$fn"; done

処理に約4分(実際)かかったソリューションを試しました。あなたのソリューションの問題は、sed70000回フォークしていることです! そしてフォークはかなり遅いです。

#!/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

乾杯!

于 2012-11-11T11:46:15.013 に答える
2

gniourf_gniourf のソリューションとほぼ同じですが、ed はありません。

for i in *.sms.txt 
do   
   while read line   
   do    
     echo $line $i
   done < $i
done >sms.txt
于 2012-11-11T14:13:25.210 に答える
2

何、愛がないのawk

awk '{print $0" "FILENAME}' *.sms.txt >sms.txt

を使用すると、私のマシンの gniourf_gniourf のサンプルで1 ~ 2 秒gawkかかりました (によると)。time

mawkここより約0.2秒速いgawkです。

于 2012-11-11T18:49:29.187 に答える
1

この perl スクリプトは、各行の末尾に実際のファイル名を追加します。

#!/usr/bin/perl
use strict;
while(<>){
    chomp;
    print $_, $ARGV, "\n";
}

次のように呼び出します。

scriptname *.sms.txt > sms.txt

プロセスが 1 つしかなく、正規表現処理が含まれていないため、非常に高速です。

于 2012-11-11T12:11:24.040 に答える