私は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
でできることはわかっていますが、使用するコマンドがわかりません。
このコマンドを試してください:
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
)。
comm
を使用できるようにするには、最初に行をソートする必要があります。
comm -23 <(sort file1.csv) <(sort file2.csv) > file3.csv
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
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