web-dev-qa-db-ja.com

2つのテキストファイルの比較

私は2つの大きなcsvファイル、file1.csvを持っています

1,2,3,4
1,4,5,6
1,7,8,9
1,11,13,17

このようなfile2.csv

1,2,3,4
1,7,8,9
2,4,9,10
13,14,17,18

これらは、私が作成した単なる乱数であり、基本的には同一でソートされた2つの数字です。 file1.csvとfile2.csvを比較し、file1.csvにはあるがfile2.csvにはない行をfile3.csvにコピーしたい。区切り文字は明らかにカンマです

私は試した

comm -2 -3 file.csv file2.csv > file3.csv

そして私は試した

diff -u file.csv file2.csv >> file3.csv

File3がfile1およびfile2よりも大きいため、両方とも機能しませんでした。さまざまなdiffおよびcommコマンドを試しましたが、file2より大きく、file file1とほぼ同じサイズである場合があります。そしてもちろん、私が望んでいた結果ではなく、file3を見ました

この時点で、diffまたはcommでできることはわかっていますが、使用するコマンドがわかりません。

6
Lynob

このコマンドを試してください:

 grep -v -f file2.csv file1.csv > file3.csv

grep manual :によると

  -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

  -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v
          is specified by POSIX.)

Steeldriverが彼のコメントで言ったように、-x-Fも追加する方が良い:

  -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
  -x, --line-regexp
          Select  only  those  matches  that exactly match the whole line.
          (-x is specified by POSIX.)

したがって、より良いコマンドは次のとおりです。

 grep -xvFf file2.csv file1.csv > file3.csv

このコマンドは、パターンとしてfile2.csv行を使用し、一致しないfile1.csvの行を印刷します(-v)。

6
Lety

commを使用できるようにするには、最初に行をソートする必要があります。

comm -23 <(sort file1.csv) <(sort file2.csv) > file3.csv
7
choroba

diffコマンドを使用するとgrepが実行され、保存は不要です。

行がfile1にあるがfile2にはない場合の出力:

$ diff file{1,2}.csv | grep -Po "^< \K.*"
1,4,5,6
1,11,13,17

そして、左の角度(<)を右の角度(>)に変更するだけで、file1にはない行がfile2に存在する場合に出力します。

$ diff file{1,2}.csv | grep -Po "^> \K.*"
2,4,9,10
13,14,17,18
3
αғsнιη

pythonオプション:

#!/usr/bin/env python3

import sys

def readfile(file):
    with open(file) as src:
        return [line.strip() for line in src.readlines()]

lines_1 = readfile(sys.argv[1]); lines_2 = readfile(sys.argv[2])

for line in lines_1:
    if not line in lines_2:
        print(line)

出力:

1,4,5,6
1,11,13,17

スクリプトをextract.pyとして空のファイルに貼り付け、実行可能にし、コマンドで実行します。

<script> <file_1> <file_2>

または、file_3に直接書き込むには:

<script> <file_1> <file_2> >file_3
3
Jacob Vlijm