У меня есть "test1.csv", и он содержит
200,400,600,800
100,300,500,700
50,25,125,310
и test2.csv и это содержат
100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5
теперь
diff test2.csv test1.csv > result.csv
отличается, чем
diff test1.csv test2.csv > result.csv
Я не знаю, который является правильным порядком, но я хочу что-то еще, обе из команд выше произведут что-то как
2 > 100,4,2,1,7
3 2,3c3,5
4 < 100,300,500,700
5 < 50,25,125,310
6 \ No newline at end of file
7 ---
8 > 21,22,23,24,25
9 > 50,25,125,310
Я хочу произвести только различие, таким образом results.csv должен быть похожим на это
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
Я попробовал diff -q
и diff -s
но они не добивались цели. Порядок не имеет значения, что имеет значение, то, что я хочу видеть только различие, нет>, ни <ни пробел.
grep -FvF
добился цели на меньших файлах не на больших
первый файл содержит больше чем 5 миллионов строк, второй файл содержит 1300.
таким образом, results.csv должен привести к ~4 998 700 строкам
Я также попробовал grep -F -x -v -f
который не работал.
Походит на задание для comm
:
$ comm -3 <(sort test1.csv) <(sort test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
, Как объяснено в man comm
:
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
Так, -3
средства, что только строки, которые уникальны для одного из файлов, будут распечатаны. Однако те располагаются с отступом, согласно которому файлу они были найдены в. Для удаления вкладки используйте:
$ comm -3 <(sort test1.csv) <(sort test2.csv) | tr -d '\t'
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
В этом случае, Вы не должны действительно даже сортировать файлы, и можно упростить вышеупомянутое до:
comm -3 test1.csv test2.csv | tr -d '\t' > difference.csv
Так как порядок не должен быть сохранен, просто:
sort test1.csv test2.csv | uniq -u
sort test1.csv test2.csv
: слияния и виды test1.csv
и test2.csv
uniq -u
: печать только строки, которые не имеют никакого дубликата Используя grep
с bash
замена процесса:
$ cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
Сохранить вывод как results.csv
:
cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv) >results.csv
grep -vFf test2.csv test1.csv
найдет строки уникальными для только test1.csv
grep -vFf test1.csv test2.csv
найдет строки уникальными для только test2.csv
Наконец мы подводим итог результатов cat
Или как предложенный Oli, можно использовать команду, группирующуюся также:
$ { grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv; }
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
Или просто выполненный один за другим, поскольку они оба пишут в STDOUT, что будут в конечном счете добавлены:
$ grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
Если порядок строк не релевантен, использовать awk
или perl
:
awk '{seen[$0]++} END {for (i in seen) {if (seen[i] == 1) {print i}}}' 1.csv 2.csv
Использовать grep
получить общие строки и фильтровать их:
grep -hxvFf <(grep -Fxf 1.csv 2.csv) 1.csv 2.csv
Внутренний grep получает общие строки, затем внешний grep находит строки, которые не соответствуют этим общим строкам.
--*-line-format=...
опции diff
Можно сказать diff
точно, в чем Вы нуждаетесь - объясненный ниже:
diff --old-line-format='%L' --new-line-format='%L' --unchanged-line-format='' f1.txt f2.txt
Возможно указать вывод разности очень подробным способом, подобным a printf
числовой формат.
Строки из первого файла, test1.csv
названы "старыми" строками и строками от второго, test2.csv
, "новые" строки. Это имеет смысл когда diff
используется для наблюдения то, что изменилось в файле.
Опции, в которых мы нуждаемся, являются теми для установки формата для "старых" строк, "новых" строк и "неизменных" строк.
Форматы, в которых мы нуждаемся, очень просты:
Для измененных строк, новых и старых, мы хотим произвести только текст строк. %L
символ формата для текста строки.
Для неизменных строк мы хотим ничего не показать.
С этим мы можем записать опции как --old-line-format='%L'
, и соединенный все это, с помощью данных в качестве примера:
$ diff --old-line-format='%L' --new-line-format='%L' --unchanged-line-format='' test1.csv test2.csv
100,4,2,1,7
100,300,500,700
21,22,23,24,25
50,25,700,5
Поскольку файлы имеют другой размер, попытайтесь обмениваться входными файлами, если он не имеет значения, могло бы случиться так что внутренние работы diff
может обработать один путь лучше, чем другой. Лучше или нуждается в меньшей памяти или меньшем количестве вычисления.
Существует опция оптимизации для использования diff
с большими файлами: --speed-large-files
. Это использует предположения о файловой структуре, таким образом, не ясно, помогает ли это в Вашем случае, но стоящий попытки его.
Параметры формата описаны в man diff
под --LTYPE-line-format=LFMT
.