Поиск строк, разделяющих информацию - PullRequest
0 голосов
/ 12 июня 2018

У меня есть файл, имеющий структуру, подобную приведенной ниже:

file1.txt:

1 10 20 A
1 10 20 B
1 10 20 E
1 10 20 F
1 12 22 C
1 13 23 X
2 33 45 D
2 48 49 D
2 48 49 E

Я пытаюсь выяснить, какие буквы имеют одинаковую информацию в 1-м, 2-м3-ий столбцы?Например, выходные данные должны быть:

A
B
E
F
D
E

Я могу только подсчитать, сколько строк уникально с помощью:

cut -f1,2,3 file1.txt | sort | uniq | wc -l 
5

, что не дает мне ничего связанного с 4-м столбцом.

Как мне получить буквы в четвертом столбце, разделяющие первые три столбца?

Ответы [ 4 ]

0 голосов
/ 12 июня 2018

используя лучшее из обоих миров ...

$ awk '{print $4 "\t" $1,$2,$3}' file | uniq -Df1 | cut -f1

A
B
E
F
D
E

поменяйте местами порядок полей, попросите uniq пропустить первое поле и вывести только дубликаты, удалить сравниваемые поля.

или,

$ rev file | uniq -Df1 | cut -d' ' -f1

A
B
E
F
D
E

если тэг не является единичным символом, вам нужно добавить | rev в конце.

NB. Оба сценария предполагают, что данные отсортированы посравниваемые ключи уже как во входном файле.

0 голосов
/ 12 июня 2018

обработать файл один раз:

awk '{k=$1 FS $2 FS $3}
     k in a{a[k]=a[k]RS$4;b[k];next}{a[k]=$4}END{for(x in b)print a[x]}' file

обработать файл дважды:

awk 'NR==FNR{a[$1,$2,$3]++;next}a[$1,$2,$3]>1{print $4}' file file

В данном примере оба однострочника, приведенные выше, дают одинаковый вывод:

A
B
E
F
D
E

Примечание первый может генерировать "буквы" в другом порядке.

0 голосов
/ 12 июня 2018

Еще один проход:

$ awk ' {
    k=$1 FS $2 FS $3        # create array key
    if(k in a) {            # a is the not-yet-printed queue
        print a[k] ORS $NF  # once printed from a...
        b[k]=$NF            # move it to b
        delete a[k]         # delete from a
    }
    else if(k in b) {       # already-printed queue
        print $NF
    } else a[k]=$NF         # store to not-yet-printed queue a
}' file
A
B
E
F
D
E
0 голосов
/ 12 июня 2018

После awk может помочь вам в этом.

 awk 'FNR==NR{a[$1,$2,$3]++;next}  a[$1,$2,$3]>1' Input_file  Input_file

Вывод будет следующим.

1 10 20 A
1 10 20 B
1 10 20 E
1 10 20 F
2 48 49 D
2 48 49 E

Чтобы получить только значение последнего поля, измените a[$1,$2,$3]>1 на a[$1,$2,$3]>1{print $NF}'

...