ターミナルで実行する次のコードがあります。
LC_ALL=C && grep -F -f genename2.txt hg38.hgnc.bed > hg38.hgnc.goi.bed
これは、2つのファイル間の共通の行を提供しません。そこで何が欠けていますか?
comm -12 file1 file2
を使用して、両方のファイルで共通の行を取得します。
期待どおりに機能するように、ファイルをcomm
にソートする必要がある場合もあります。
comm -12 <(sort file1) <(sort file2)
man comm
から:
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
またはgrep
コマンドを使用して、-x
オプションを追加し、行全体を一致パターンとして一致させる必要があります。 F
オプションは、grep
にパターンに一致することを正規表現一致ではなく文字列として通知します。
grep -Fxf file1 file2
またはawk
を使用します
awk 'NR==FNR{seen[$0]=1; next} seen[$0]' file1 file2
これはfile1の行全体を、キーを行全体としてseen
という配列に読み取ります(awk
では、$0
は現在の行全体を表します)。
NR
のawk
は現在の処理行番号を参照し、FNR
は次のようになるため、NR==FNR
を条件として使用して、後続のブロックを最初の入力に対してのみ実行しますfle1file2ではありません。 all入力で現在の行番号を参照します。したがって、NR
は各入力ファイルに対して一意ですが、FNR
はすべての入力に対して一意です。
next
は、awk
がNR
と等しくない、つまりFNR
によって読み取られるfile1のすべての行が等しくなるまでawk
が残りのコードを続行せずに再開することを伝えています。
次に、次のseen[$0]
は2番目にのみ実行されますfile2file2の各行で配列を調べ、その行が配列内に存在する場所に出力します。
別の簡単なオプションは、sort
とuniq
を使用しています:
sort file1 file2|uniq -d
これにより、両方のファイルがソートされて印刷され、uniq -d
は重複する行のみを印刷します。しかし、これは両方のファイル自体に重複する行がない場合に許可されます。それ以外の場合は、両方のファイル内に重複する行がある場合でも常に許可されます。
uniq -d <(sort <(sort -u file1) <(sort -u file2))
Linuxで実行しているので、それはGNU/Linuxであり、GNU diff
コマンドを使用していると思います。
GNU diff
コマンドを実行している場合、これは変更されたすべての行と一般的な行を表示する方法です。
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"
これは従来のdiff
出力に似ていますが、ファイル名や区切り線は出力に表示されず、古い行には-
が付いており、新しい行には+
が前に付いています。先頭にスペースが付きます。
シェルスクリプトの例とテストファイルの結果の出力を次に示します。
$ cat diffcomm.sh
#!/bin/sh
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"
$ cat > filea
a
b
c
d
$ cat > fileb
a
z
d
$ ./diffcomm.sh filea fileb
a
-b
-c
+z
d
$
ラインのクラスごとに出力フォーマットを変更できます。
詳細については、man diff
またはinfo diff
または GNU diffutilsのドキュメント を参照してください。