Сравните определенные столбцы в нескольких файлах и распечатайте соответствующий конкретный столбец

#join #awk

Вопрос:

У меня есть несколько файлов (шесть файлов) в формате csv. Я пытаюсь сравнить $3,$4,$5 в нескольких файлах и, если совпадение, напечатать $6 из всех файлов вместе со столбцом $2,$3,$4,$5 из файла 1.

Входной файл 1:

 Blink,Seeddensity(g/cm^3),1_0002,VU10,37586764,0.458533399568206
Blink,Seeddensity(g/cm^3),1_0004,VU08,37687622,0.548181169267479
Blink,Seeddensity(g/cm^3),1_0006,VU02,6629660,0.553099787284982
 

Входной файл 2:

 Farmcpu,Seeddensity(g/cm^3),1_0002,VU10,37586764,0.907010463957269
Farmcpu,Seeddensity(g/cm^3),1_0004,VU08,37687622,0.782521980037194
Farmcpu,Seeddensity(g/cm^3),1_0006,VU02,6629660,0.589126094555234
 

Входной файл 3:

 GLM,Seeddensity(g/cm^3),1_0002,VU10,37586764,0.24089
GLM,Seeddensity(g/cm^3),1_0004,VU08,37687622,0.25771
GLM,Seeddensity(g/cm^3),1_0006,VU02,6629660,0.31282
 

Желаемый результат:

 Trait   Marker  Chr Pos Blink   Farmcpu GLM
Seeddensity(g/cm^3) 2_27144 VU08    36984438    1.7853934213866E-11 0.907010463957269   0.24089
Seeddensity(g/cm^3) 2_13819 VU08    21705264    3.98653459293212E-09    0.782521980037194   0.25771
Seeddensity(g/cm^3) 2_07286 VU01    38953729    3.16663946775461E-07    0.589126094555234   0.31282
 

Я проверил несколько команд awk, но эта самая близкая из них выполняет работу в двух файлах:

 awk 'NR==FNR{ a[$2,$3,$4,$5]=$1; next } { s=SUBSEP; k=$2 s $3 s $4 s $5 }k in a{ print $0,a[k] }' File1 File2 > output

join <(sort File1) <(sort File2) | join - <(sort File3) | join - <(sort File4) | join - <(sort File5) | join - <(sort File6) > output
 

Я считаю, что соединение не работает, так как первый столбец не совпадает между файлами, поэтому я попробовал эту команду:

 join -t, -j3 -o 1.2,1.3,1.4,1.5,1.6,2.6,3.6,4.6,5.6,6.6 <(sort -k 3 File1) <(sort -k 3 File2) <(sort -k 3 File3) <(sort -k 3 File4) <(sort -k 3 File5) <(sort -k 3 File6) > output
 

Но я получаю сообщение об ошибке msg:
регистрация: неверный номер файла в спецификации поля: ‘3.6’

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

 join -t, -j3 -o 1.2,1.3,1.4,1.5,1.6,2.6 <(sort -k 3 File1) <(sort -k 3 File2) > output
 

Комментарии:

1. Вы говорите, что ваш ввод-это CSV, но предоставленный вами образец ввода не является CSV (может быть, он разделен вкладками?). Пожалуйста, исправьте, какая из этих 2 вещей неверна, описание или пример, и предоставьте свою попытку решить вашу проблему самостоятельно, чтобы мы могли вам помочь.

2. Файлы в формате csv, я ранее скопировал их из excel, чтобы их можно было четко визуализировать, я добавил некоторые коды.

3. да, никогда не предоставляйте какое-либо представление ваших данных, просто предоставляйте свои данные, чтобы мы могли предоставлять точные решения и копировать/вставлять их для тестирования. Я вижу, что вы обновили свой образец ввода в CSV, но ожидаемый результат не является CSV. Является ли это преднамеренным и точным или это оплошность? Если последнее, пожалуйста, исправьте это.

Ответ №1:

Предполагая, что вам действительно нужен вывод CSV, затем используйте GNU awk для ARGIND:

 $ cat tst.awk
BEGIN { FS=OFS="," }
{ key = $3 FS $4 FS $5 }
ARGIND < (ARGC-1) {
    val[key,ARGIND] = $6
    next
}
{
    sfx = ""
    for (i=1; i<ARGIND; i  ) {
        if ( (key,i) in val ) {
            sfx = sfx OFS val[key,i]
        }
        else {
            next
        }
    }
    print $2, $3, $4, $5, $6 sfx
}
 
 $ awk -f tst.awk file2 file3 file1
Seeddensity(g/cm^3),1_0002,VU10,37586764,0.458533399568206,0.907010463957269,0.24089
Seeddensity(g/cm^3),1_0004,VU08,37687622,0.548181169267479,0.782521980037194,0.25771
Seeddensity(g/cm^3),1_0006,VU02,6629660,0.553099787284982,0.589126094555234,0.31282
 

С любым другим awk просто добавьте строку, которая FNR==1 { ARGIND } находится в начале сценария.

Комментарии:

1. Большое спасибо, это хорошо сработало для трех входных файлов, но у меня всего шесть файлов, поэтому, если я попытаюсь предоставить шесть входных файлов, он начнет добавлять выходные данные к выходным данным первых трех входных файлов

2. Хорошо, я изменил его, чтобы он работал для любого количества входных файлов.