@Masi のリクエストに応じて、sed を使用して解決策を見つけようとしました。
私の最初の試みは 2 つのパスを使用します。最初file1は sed スクリプトに変換され、2 番目のパスで filter に使用されますfile2。
sed 's/\([^ \t]*\).*/\/^\1\t\/p;t/' file1 > sed1
sed -nf sed1 file2 > out2
大きな入力ファイルでは、これは遅くなります。の各行に対してfile2、sed は の行数に等しい量のパターンを処理する必要がありますfile1。私はプロファイリングを行っていませんが、時間の計算量が 2 次であっても驚かないでしょう。
2 回目の試行では、2 つのファイルをマージして並べ替え、すべての行をスキャンしてペアを探します。これは線形時間で実行されるため、はるかに高速です。この解決策は、ファイルの元の順序を台無しにすることに注意してください。この日付表記では、アルファベット順の並べ替えがうまく機能しません。これを修正する最も簡単な方法は、異なる日付形式 (ymd) のファイルを提供することです。
sed 's/^[^ \t]\+/&@1/' file1 > marked1
sed 's/^[^ \t]\+/&@2/' file2 > marked2
sort marked1 marked2 > sorted
sed '$d;N;/^\([^ \t]\+\)@1.*\n\1@2/{s/\(.*\)\n\(.*\)/\2\n\1/;P};D' sorted > filtered
sed 's/^\([^ \t]\+\)@2/\1/' filtered > out2
説明:
- 最初のコマンドで、すべての日付に
s/^[^ \t]\+/&@1/追加@1します。これにより、ファイルをマージしたり、並べ替え時に同じ日付を保持したり、異なるファイルの行を区別したりできます。
- 2 番目のコマンドは
file2;に対して同じことを行います。明らかに独自のマーカーを使用します@2。
- この
sortコマンドは、2 つのファイルをマージして、同じ日付をグループ化します。
- 3 番目の sed コマンドは
file2、 にも含まれる日付を持つからのすべての行を返しますfile1。
- 4 番目の sed コマンドは
@2、出力からマーカーを削除します。
3 番目の sed コマンドの詳細:
$d最後の行の不適切な印刷を抑制します
N別の入力行を読み取り、パターン空間に既に存在する行に追加します
/^\([^ \t]\+\)@1.*\n\1@2/異なるファイルに由来するが同じ日付の 2 つの行に一致します
{コマンドグループを開始します
s/\(.*\)\n\(.*\)/\2\n\1/パターン空間の 2 行を入れ替えます
Pパターンスペースの最初の行を印刷します
}コマンドグループを終了します
Dパターンスペースから最初の行を削除します
悪いニュースは、2 番目のアプローチでさえ、@ John1024 による awk アプローチよりも遅いことです。Sed はマージ ツールとして設計されたことはありません。どちらも awk ではありませんでしたが、awk にはファイル全体を辞書に格納できるという利点があり、@ John1024 のソリューションは非常に高速です。ディクショナリの欠点はメモリ消費です。巨大な入力ファイルでは、私のソリューションが有利になるはずです。