web-dev-qa-db-ja.com

「sort」を使用した複数のファイルのマージと並べ替え

次の形式のテキストログファイルがたくさんあります。

ID          (17 characters)
Timestamp   (14 characters YYYYmmddHHMMSS e.g. "20060210100040" -> 2006/02/10 10:00:40)
Random data (? characters)
end of line

ファイルはすでにタイムスタンプでソートされています。タイムスタンプでソートされた、複数のログファイルからのすべてのログを含む1つのログファイルを取得する必要があります。ログファイルは非常に大きく、それぞれ約3〜4Gであることに注意してください(数十個あります)。次のコマンドを試しました。

sort -s -m -t '|' -k1n,1n +17 -o data_sort.txt *.TXT

これが私がこのコマンドで終わった方法です:

-s     : don't bother with tie results
-m     : merge all logs files
-t '|' : there is no | in my logs, so the whole line should be field 1
-k1n,1n: sort on the first field as a numeric value
+17    : the timestamp starts at index 17
-o     : output file

実は…惨めに失敗します。出力ファイルdata_sort.txtは、すべてのファイルを連結したものであり、まったくソートされていません:(

誰かがこの問題について何か助けを提供してくれれば幸いです!

ありがとう

9
NewbiZ

キーは-k1.17nで、-t+17を省略します。

IDとタイムスタンプの間にスペースはありますか?次に、タイムスタンプはフィールド2で、キーは-k2になります。

man sort読み取り:

-m、--mergeソート済みのファイルをマージします。 ソートしないでください

「+」記号がソート用のmanページに表示されません。だから私はあなたが+17を得る方法がわかりません。行全体を使用する場合は、notneed -tまたは-k、デフォルトでは行頭から行末までソートを開始するため。

9
Felipe Alvarez

私はこれらのハードなものが好きです...これは私に考えさせられました:

基本的に、すべての.txtファイルを連結し、コロンで区切り(並べ替え用)、2番目のフィールドを並べ替え(rは最新のものを最初に並べ替え、最新のものが必要な場合は取り出します)、コロンを削除して元の行を表示します。

cat *.txt
 | awk '{print substr($0,1,17)":"substr($0,18,14)":"substr($0,32)}'
 | sort -t: -k2,2 -nr -s
 | tr -d ':'

3つの4行の.txtファイルでテストしました。

最初のファイル

1234567890123456720100603104500Random text or data
2345678901234567820100602104500New Random Text
3456789012345678920100509213849Earlier Date
4567890123456789020100521195058InBetween Date

2番目のファイル

1234567890123456720100603124500File2 Random text or data
2345678901234567820100602124500File2 New Random Text
3456789012345678920100519213849File2 Earlier Date
4567890123456789020100523195058File2 InBetween Date

番目のファイル

12345678901234567201106031045003Random text or data
23456789012345678201004021045003New Random Text
34567890123456789201007092138493Earlier Date
45678901234567890201005231950583InBetween Date

結果

12345678901234567201106031045003Random text or data
34567890123456789201007092138493Earlier Date
1234567890123456720100603124500File2 Random text or data
1234567890123456720100603104500Random text or data
2345678901234567820100602124500File2 New Random Text
2345678901234567820100602104500New Random Text
4567890123456789020100523195058File2 InBetween Date
45678901234567890201005231950583InBetween Date
4567890123456789020100521195058InBetween Date
3456789012345678920100519213849File2 Earlier Date
3456789012345678920100509213849Earlier Date
23456789012345678201004021045003New Random Text
2
Theo

最初にcatを使用してファイルを連結してから、並べ替えてみてください。 sortは、stdinからの単一の入力ストリームを認識するため、複数のファイルについて混乱することはありません。

-t-kに使用しているオプションの組み合わせは、通常の種類以外でこれを実行しようとしているようです。ソートは、特定の区切り文字(デフォルトでは空白)を持つフィールドで動作します。

おそらく、cut(フィールドをバイト単位で分割するため)、awkを使用してそれらをつなぎ合わせ、sortを使用して行を並べ替え、次にawkを使用して行を元の形式で再作成することをお勧めします。

0
Doug Harris