web-dev-qa-db-ja.com

最初の列に基づいて2つのファイルを比較し、一致しないものを印刷します

ファイル番号1:

test1,1
test2,2
test3

ファイル番号2:

test2
test1
test4

目的の出力:

test4

これにはgrepを使用できます。

_$ grep -vwf <(cut -d, -f1 file1) file2
test4
_

説明

  • grepオプション:

    _-v, --invert-match
          Invert the sense of matching, to select non-matching lines.
    -w, --Word-regexp
          Select  only  those  lines  containing  matches  that form 
          whole words.  
    -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  
    _

    したがって、組み合わせて_grep -vwf patternFile inputFile_は、「inputFileに単語全体として存在することのないpatternFileからの行を見つける」ことを意味します。

  • <(command):これはプロセス置換と呼ばれ、それをサポートするシェル(bashなど)では、基本的にファイルのように機能します。これにより、cutコマンドの出力をgrepの_-f_オプションの「ファイル」として使用できるようになります。

  • _cut -d, -f1 file1_:file1の最初のコンマ区切りフィールドのみを出力します。

データが実際に表示されているとおりである場合は、_-x_だけでなく、_-w_(行全体に一致)を使用することをお勧めします。

_  -x, --line-regexp
          Select  only  those  matches  that exactly match the whole line.
_

そう:

_$ grep -vxf <(cut -d, -f1 file1) file2
test4
_

また、_file1_に正規表現文字(_._、_*_、_?_など)を含めることができる場合は、_-F_も使用できます。

_  -F, --fixed-strings
          Interpret PATTERNS as fixed strings, not regular expressions.
_

そう:

_$ grep -Fvxf <(cut -d, -f1 file1) file2
test4
_
3
terdon

cutgrepの使用:

grep -F -x -v -f <(cut -d',' -f1 file1) file2

cut -d',' -f1 file1file1の最初のフィールドを出力し、grepは出力をパターン入力ファイルとして使用します(オプション-f)。オプション-Fおよび-xは、固定文字列と行全体を照合するために使用され、-vは照合を逆にします。

2
Freddy
:~$ cat > toto
a b
c d
e f
:~$ cat > titi
a b
d e
f g
:~$ awk 'NR==FNR{c[$1]++;next};c[$1] == 0' toto titi
d e
f g

これは、例のリストから取得した例にすぎません。これを使用して、独自のニーズを回避できます。

1
francois P

file1の最初のフィールドにファイル名が含まれ、フィールド区切り文字が常に,であると仮定すると、awkの可能性があります。

awk -F"," 'NR==FNR{test[$1]=1}NR!=FNR{if (!test[$1]) print $1}' file1 file2

(コメントの@Terdon合理化バージョンを参照してから、私のものと組み合わせる

awk -F"," 'NR==FNR{test[$1]++}!test[$1]{print $1}' file1 file2

joinを使用する代替手段

join -t, -v2 <(sort file1) <(sort file2)
1
bu5hman

まさにその設定のために、

grep -ffile2 -v file1
test3

しましょう。ただし、たとえば次の点に注意してください。追加の対策を講じる必要がある誤検知。

0
RudiC