@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 のソリューションは非常に高速です。ディクショナリの欠点はメモリ消費です。巨大な入力ファイルでは、私のソリューションが有利になるはずです。