Сравнение пар полей между файлами с учетом смещения - PullRequest
0 голосов
/ 05 июля 2018

Я пытался решить довольно сложную проблему (по крайней мере, это сложно для кого-то новичка в этом, как я). У меня есть файл ("file1") с сотнями тысяч строк, которые выглядят так (включая больше полей, чем показано):

1 name1 18 25 A1 ID1
2 name2 28 34 A1 ID1
3 name2 71 123 A2 ID2
4 name3 9 56 A5 ID5
5 name3 9 89 A7 ID7

Мой следующий файл ("file2"), также большой, выглядит следующим образом:

1 name1 18 25 52 59 65 78 94 134
2 name1 18 25 52 58
3 name2 28 34 71 123
4 name2 27 35 42 59 61 68 71 125 156 198 206 287
5 name2 28 31 43 56 71 123 158 200

Таким образом, каждая строка file2 содержит «пары» значений (т. Е. Поля $ 3 и $ 4, поля $ 5 и $ 6 и т. Д.), Некоторые из которых соответствуют «парам» в file1 (поля $ 3 и $ 4) всякий раз, когда мы находимся в строке, начинающейся с одного и того же имени в обоих файлах. Одним из примеров этого является первая пара строки 3 в файле2, соответствующая паре в строке 2 файла1. Некоторые пары соответствуют почти (например, $ 3 и $ 4 строки 4 в файле2 со строкой 2 в файле1). Пара из file1 может встречаться только один раз в каждой строке в file2.

То, что я хочу сделать, - это если строки из двух файлов с одинаковым «именем» (то есть с тем же полем $ 2 в этом случае), попытаться сопоставить каждую пару в файле2 с парами файла1 и, если есть совпадение, выведите новый файл, содержащий другую информацию из файла file1 в формате file2. Другими словами, я хочу заменить пары чисел в file2 информацией «A» и «ID» из file1 (столбцы $ 5 и $ 6). Если в файле file1 не найдено совпадений для пары в файле file2, выходные данные должны быть помечены, например, как «not found». Обратите внимание, что первое и второе значения пар должны совпадать между файлами.

Твист (ы):

Прежде всего, строки файла2 содержат разное количество пар (чуть более ста столбцов).

Во-вторых, Я хочу принимать "нечеткие" совпадения . Под этим я подразумеваю принимать любые значения из file2, скажем, +/- 5 от фактических значений в file1 (то есть (значение в file1) -5 <(значение в file2) <(значение в file1) +5) , </p>

Значения во входных файлах в действительности намного больше, чем показано в примерах. В целом вывод в этом случае будет выглядеть примерно так ("file3"):

1 name1 A1 ID1 not found not found not found
2 name1 A1 ID1 not found
3 name2 A1 ID1 A2 ID2
4 name2 A1 ID1 not found not found A2 ID2 not found not found
5 name2 A1 ID not found A2 ID2 not found

До сих пор я безуспешно лаял дерево awk в своем поиске решения.

Я буквально застрял. Любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 05 июля 2018

Использование GNU awk для истинных многомерных массивов:

$ cat tst.awk
NR==FNR {
    a[$2][$3][$4][5] = $5
    a[$2][$3][$4][6] = $6
    next
}
$2 in a {
    for (i=3; i<=NF; i+=2) {
        hit = 0
        for (key3 in a[$2]) {
            if ( abs($i - key3) < 5 ) {
                for (key4 in a[$2][key3]) {
                    if ( abs($(i+1) - key4) < 5 ) {
                        hit = 1
                        break
                    }
                }
                if (hit) {
                    break
                }
            }
        }
        $i     = (hit ? a[$2][key3][key4][5] : "not")
        $(i+1) = (hit ? a[$2][key3][key4][6] : "found")
    }
}
{ print }
function abs(v) { return (v<0 ? -v : v) }

.

$ awk -f tst.awk file1 file2
1 name1 A1 ID1 not found not found not found
2 name1 A1 ID1 not found
3 name2 A1 ID1 A2 ID2
4 name2 A1 ID1 not found not found A2 ID2 not found not found
5 name2 A1 ID1 not found A2 ID2 not found
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...