сравнение данных в двух файлах - PullRequest
0 голосов
/ 17 июня 2011

У меня есть два файла с разделителями табуляции.

Файл 1 (10 строк и, скажем, 4 столбца, эти столбцы могут не заполняться в каждой строке):

Chra stra stpa NM1 NM2 NR1
Chrb strb stpb NR2 NM1

Файл 2 (25 строк и 3 столбца):

Tg NM1 12
Tg NM3 3
Tg NR1 76

Теперь я хочу сравнить идентификаторы NM и NR в каждой строке файла 1 с файлом 2i f в любом месте совпадения идентификатора NR файла2.Он должен извлечь соответствующее значение идентификатора NR / NM из файла 2.

Файл 3 может выглядеть так (скажем, для NM1):

chra stra stpa NM1 12
chra stra stpa NR1 76

Есть предложения для сценария оболочки?

Ответы [ 3 ]

2 голосов
/ 17 июня 2011
$ join -1 4 -2 2 \
<(for i in 4 5 6 7; do join -e _ -j $i f1 f1 -o 1.1,1.2,1.3,0; done |
  sed '/_$/d' | sort -k4,4) \
<(sort -k2,2 f2) \
-o 1.1,1.2,1.3,0,2.3

Chra stra stpa NM1 12
Chrb strb stpb NM1 12
Chra stra stpa NR1 76
0 голосов
/ 17 июня 2011
awk '
    NR == FNR {tag[$2] = $3; next}
    {
        # determine if this line has a "NR" tag from file2
        have_nr = 0
        for (i=4; i<=NF; i++) {
            if ($i ~ /^NR/ && $i in tag) {
                have_nr = 1
                break
            }
        }

        # if it does have a matching NR tag, then
        # print the tag value for every matching NR/NM tag
        if (have_nr) {
            for (i=4; i<=NF; i++) {
                if ($i in tag) {
                    print $1, $2, $3, $i, tag[$i]
                }
            }
        }
    }

' file2 file1
0 голосов
/ 17 июня 2011

Вместо сценария оболочки, я бы сделал это с помощью сценария Perl. Вы можете использовать функцию split (), чтобы получить массив со всеми «полями» для каждой строки, и оттуда все будет по склону. Не нужно придумывать причудливое регулярное выражение. Здесь s пример такого рода действий:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...