Сравните 2 одинаковых файла и выводите только различия, сохраняя порядок, в котором они встречаются? - PullRequest
3 голосов
/ 20 декабря 2011

в надежде, что кто-нибудь поможет мне разобраться с этим

У меня есть 2 файла, один длиной 325 строк, один длиной 361 строк.

Основная масса этих файлов идентична, но во 2-й вставлены случайные дополнительные строки.Меня интересуют только дополнительные строки, и мне нужно сохранить порядок, в котором они встречаются в файле.

Файлы содержат повторяющийся абзац приблизительно из 31 строки - я знаю первую и последнюю строку этогоабзац, и не имеет проблем с удалением всего абзаца, но не могу понять, как.

т.е. File1

The quick brown
fox jumped 
over the
lazy dog
The quick brown
fox jumped
over the
lazy dog
The quick brown
fox jumped
over the
lazy dog

ie File2

The quick brown
fox jumped
over the
lazy dog
sadhasdgh
qyyutrytkdaslksad
utyiuiytiuyo
The quick brown
fox jumped
over the
lazy dog
djakdjhgmv
asdjkljkgfyiyi
The quick brown
fox jumped
over the
lazy dog
jghytpuptou

Мне нужно вывести только дополнительные строки в следующем порядке:

sadhasdgh
qyyutrytkdaslksad
utyiuiytiuyo
djakdjhgmv
asdjkljkgfyiyi
jghytpuptou

Anyпомощь или совет будут с благодарностью приняты, к сожалению, я не * nix человек :( Я пробовал несколько выражений diff и выражений comm, но не могу получить то, что мне нужно.

Ответы [ 4 ]

3 голосов
/ 20 декабря 2011

Попробуйте эту магическую команду:

diff file1.txt file2.txt | sed -n 's/^> \(.*\)/\1/p'

diff file1.txt file2.txt должно вывести что-то вроде

2c2
< fox jumped 
---
> fox jumped
4a5,7
> sadhasdgh
> qyyutrytkdaslksad
> utyiuiytiuyo
8a12,13
> djakdjhgmv
> asdjkljkgfyiyi
12a18
> jghytpuptou

sed -n 's/^> \(.*\)/\1/p' должен найти строки, начинающиеся с >, и вывести эти строки без >. Возможная причина, по которой это не работает, - разный вывод diff в вашей системе?

1 голос
/ 20 декабря 2011

Это должно работать -

awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file1 file2

Explaination:

NR и FNR равны awk's built-in variables. NR регистрирует количество записей и не сбрасывается до 0 при работе с двумя файлами. FNR аналогично NR, но сбрасывается до 0 после полного анализа файла.

В этом awk однострочнике мы сохраняем условие NR==FNR, которое заставляет действие {a[$0]++;next} только для файла1 (так как NR==FNR будет истинно, пока мы не будем работать с file1). Это действие сохраняет каждую строку в array. next добавляется, чтобы second action не вызывался. Как только этот NR==FNR становится untrue, first action никогда не вызывается. awk переходит к second action, который проверяет содержимое file2 относительно array (т.е. file1). Если содержимое file2 находится в array, мы игнорируем его. Если его нет в массиве, мы печатаем его, поскольку эти строки будут extra и только в file2.

Тест:

File1:

[jaypal:~/Temp] cat file1
The quick brown
fox jumped 
over the
lazy dog
The quick brown
fox jumped
over the
lazy dog
The quick brown
fox jumped
over the
lazy dog

File2:

[jaypal:~/Temp] cat file2
The quick brown
fox jumped
over the
lazy dog
sadhasdgh
qyyutrytkdaslksad
utyiuiytiuyo
The quick brown
fox jumped
over the
lazy dog
djakdjhgmv
asdjkljkgfyiyi
The quick brown
fox jumped
over the
lazy dog
jghytpuptou

Исполнение:

[jaypal:~/Temp] awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file1 file2
sadhasdgh
qyyutrytkdaslksad
utyiuiytiuyo
djakdjhgmv
asdjkljkgfyiyi
jghytpuptou
0 голосов
/ 22 декабря 2011
diff -b sample.log sample.log.1 | awk '/>/ {print $2}'
0 голосов
/ 21 декабря 2011

Это может работать для вас (GNU diff):

diff -bu file1 file2 | sed -n '1,2d;s/^+//p'
sadhasdgh
qyyutrytkdaslksad
utyiuiytiuyo
djakdjhgmv
asdjkljkgfyiyi
jghytpuptou
...