как я могу напечатать разностный номер строки, игнорируя 1-й столбец для файлов, разделенных табуляцией?
пример - сравните файл 1 с файлом 2, игнорируя 1-й столбец и номер строки печати. для записи о разнице, присутствующей в файле 2.
В файле1:
user1 fistname Lastnamename
user2 Johnny Depp
user3 Tom Cruise
user4 Leonardo DiCaprio
user5 Sylvester Stallone
и
В файле2:
user10 fistname Lastnamename
user2 Johnny Depp
user30 Tom' Cruise
user4 Nicolas Cage
user50 Sylvester Stallone
ожидаемый результат: - разница в файле2 для строки номер 3,4
Примечание. Размер файла для сравнения указан в ГБ, а файл разделен табуляцией
Попробуйте использовать этот код, не знаю, сработает ли он, так как у меня недостаточно данных:
diff --unchanged-line-format="" --old-line-format="" --new-line-format=":%dn: %L" file1 file2 | sed 1d | cut -d':' -f2 |tr '\n' ','|sed 's/,$//g'
Вы можете использовать команду diff вместе с cut, чтобы найти разницу в двух файлах.
diff <(cut -f2 -d$'\t' file1) <(cut -f2 -d$'\t' file2)
Результатом будет
3,4c3,4
< Tom
< Leonardo
---
> Tom'
> Nicolas
. Если вас беспокоит большее количество повторяющихся записей, вы можете использовать указанную выше команду с sort -u
для удаления дубликатов перед поиском различий в другом файле. Команда будет
diff <(cut -f2 -d$'\t' file1|sort -u) <(cut -f2 -d$'\t' file2|sort -u)
$ echo -n 'difference in file2 is for line number ';diff --unchanged-line-format="" --old-line-format="" --new-line-format="%dn " <(tail +2 file1|unexpand -a|cut -f2-) <(tail +2 file2|unexpand -a|cut -f2-)|grep -o "[0-9]*" | while read i;do echo $((i+1));done|paste -sd,
difference in file2 is for line number 3,4
Это может ответить на ваш вопрос:
awk 'NR==FNR{++a[$2,$3];next} {line++;if(!(a[$2,$3])){print line}}' record1 record2
Объяснение:
FNR==NR
Когда у вас есть два (или более) входных файла для awk
, FNR вернется к 1
при первом строки следующего файла, тогда как NR будет продолжать увеличивать
с того места, где было остановлено. Проверяя FNR == NR
, мы, по сути, проверяем
, чтобы увидеть, анализируем ли мы в данный момент первый файл.
++a[$2,$3]
Если мы анализируем первый файл (см. Выше), то создаем ассоциативный массив с первым полем $ 2 и вторым полем $ 3 в качестве ключа и после увеличения значения на 1. Это, по сути, позволяет нам создать список "видели".
next
Эта команда указывает awk не обрабатывать дальнейшие команды, а читать следующую запись и начинать заново. Мы делаем это, потому что file1 предназначен только для установки ассоциативного массива
!(a[$2,$3])
Эта строка выполняется только тогда, когда FNR == NR ложно, т.е. мы не анализируем file1 и, следовательно, должны анализировать file2. Затем мы используем первое поле $ 1 и второе поле $ 2 файла file2 в качестве ключа для индексации в нашем «просмотренном» списке, созданном ранее. Если возвращенное значение равно 0, это означает, что мы не видели его в file1, и поэтому мы должны распечатать эту строку. И наоборот, если значение не равно нулю, то мы действительно видели его в file1, и поэтому нам не следует печатать его значение. Обратите внимание, что! (A [$ 2, $ 3]) эквивалентно! (a [$ 2, $ 3]) {print}, потому что действие по умолчанию, когда оно не задано, - это распечатать всю строку.