2つのテキストファイルがあり、それを1つにマージしたいとします。
2 番目のファイルは最初のファイルの行で始まるので、その行の一部が繰り返されます。重複した内容があります。
これらのファイルをどのようにマージできますか?
もちろん、一般的なバイナリといくつかの部分のためのソリューションは理想的に歓迎されています。
答え1
短くて良い解決策のように見えるのはどこにも存在しますが、不吉なawk重複排除機です。
awk '!x[$0]++'
重複した項目を削除するだけでなく、入力ファイルの元の順序も維持します。以下は、コマンドの動作方法の説明です。awk '!a[$0]++' はどのように機能しますか?
このようにしてください
awk '!x[$0]++' file1 file2
まず、file1を印刷してから重複せずにfile2を印刷します。重複した部分は重複しているため削除されます。
しかし、注意してください!削除されます。みんなファイルに重複があります。観察する:
$ cat file1
a
b
b
overlap1
overlap2
$ cat file2
overlap1
overlap2
p
q
q
$ awk '!x[$0]++' file1 file2
a
b
overlap1
overlap2
p
q
また、重ならない重複行も削除します。
ファイルが複製されていないか、とにかく削除したい場合は、このコマンドを使用してください。
重複した行を維持するために読んでください。
重複を削除せずに重複を手動で削除する方法は次のとおりです。自動化することもできますが、努力をしませんでした。
まず、最初のファイルから最後の行を取得します。
$ tail -n1 file1
overlap2
2番目のファイルから、この行の前のすべての行を削除します。
$ sed '0,/overlap2/d' file2
p
q
q
file1を2番目のコマンドの結果に関連付けると、重複することなくリンクされたファイルが得られますが、重複は保持されます。
$ cat file1 <(sed '0,/overlap2/d' file2)
a
b
b
overlap1
overlap2
p
q
q
これはうまく機能し、ほとんどの場合うまくいきます。
しかし、注意してください!重複したコンテンツがある場合、すべての重複コンテンツは削除されません。観察する:
$ cat evil1
a
b
overlap1
overlap2
overlap3
overlap1
overlap2
$ cat evil2
overlap1
overlap2
overlap3
overlap1
overlap2
p
overlap2
q
最初のファイルの最後の行を決定します。
$ tail -n1 evil1
overlap2
2番目のファイルから最初の項目を削除する
$ sed '0,/overlap2/d' evil2
overlap3
overlap1
overlap2
p
overlap2
q
重複したアイテムがある場合、最初のアイテムだけを削除しても、すべての重複アイテムが削除されるわけではありません。ただし、間違った行のため、overlap2
最後のエントリも削除できません。
それでは、最大重なりを決定する方法は何ですか?まず、file2 の file1 で最後の行が現れるものをすべて探します。各発生の重複をテストします。その後、まだ重複する最後のイベントを取得します。
すべてのアイテムを探す
$ grep -n overlap2 evil2
2:overlap2
5:overlap2
7:overlap2
それぞれが重なっているかテスト
$ diff -q <(tail -n2 evil1) <(head -n2 evil2)
$ diff -q <(tail -n5 evil1) <(head -n5 evil2)
$ diff -q <(tail -n7 evil1) <(head -n7 evil2)
Files /dev/fd/63 and /dev/fd/62 differ
出力がないということは違いがないことを意味します。 2つの線が重なります。 5つの要素も重なります。しかし、7行はもはや重なりません。これは、行5の発生が最大ネストされ、行7の発生がネストとは無関係であることを意味します。
$ cat evil1 <(sed '1,5d' evil2)
a
b
overlap1
overlap2
overlap3
overlap1
overlap2
p
overlap2
q
言ったように、これは自動化できますが、努力をしませんでした。
関連xkcd:https://xkcd.com/974/
少なくとも私はこの答えに努力しました。楽しんでください。
答え2
順序が重要でない場合は、次のコマンドを使用して操作を完了できます。
sort -u FILE1 FILE2 > FILE3
ファイルの順序が重要な場合は、次のコマンドを使用します。
cat -n FILE1 FILE2 | sort -uk2 | sort -nk1 | cut -f2- > FILE3