2015-05-08 3 views
1

У меня есть два файла, как показано ниже, которые являются разделителями табуляции:Как добавить новый столбец из другого файла в AWK

файл А

123,789 aa b c d 
123  aa b c d 
234  a b c d 
345  aa b c d 
456  a b c d 
.... 

файл B

123 add c d e 
345 add e f g 
789 sub e f g 
... 

Я хочу добавить столбец 2 из файла B в файл A на основе столбца 1, который будет выглядеть следующим образом: вывод:

123,789 add,sub aa b c d 
123  add  aa b c d 
234    a b c d 
345  add  aa b c d 
456    a b c d 
.... 

Я попытался с помощью:

awk 'NR==FNR{a[$1]=$2;next}{$2=a[$1]FS$2;print}' OFS='\t' fileB file A 

, который дает выход:

123,789   aa b c d 
123  add  aa b c d 
234    a b c d 
345  add  aa b c d 
456    a b c d 

Проблема с колонками и несколько строк, разделенных запятой в column1 из файла А. Код AWK лечит это единственная строка, из-за которой она не может соответствовать файлу. Может ли кто-нибудь отредактировать код awk или любое исправление. Благодарю.

ответ

1

Я бы сказал, что

awk -F '\t' 'BEGIN { OFS = FS } NR == FNR { saved[$1] = $2; next } { n = split($1, a, ","); sep = ""; field = ""; for(i = 1; i <= n; ++i) { if(a[i] in saved) { field = field sep saved[a[i]]; sep = "," } } $1 = $1 OFS field } 1' fileB fileA 

То есть:

BEGIN { OFS = FS }     # Output separated like input 

NR == FNR {       # while processing fileB: 
    saved[$1] = $2     # just remember stuff 
    next 
} 

{         # while processing fileA: 
    n = split($1, a, ",")    # split first field at commas 

    sep = ""      # reset temps 
    field = "" 

    for(i = 1; i <= n; ++i) {   # wade through comma-separated parts of $1 
    if(a[i] in saved) {    # if a corresponding line existed in fileB 
     field = field sep saved[a[i]] # append it to the new field 
     sep = ","      # from the second forward, separate by "," 
    } 
    } 

    $1 = $1 OFS field     # insert the new field into the line 
} 
1         # then print. 
+0

В основном такой же, как у меня, но в комплекте с объяснением. Не стесняйтесь брать какие-либо биты, которые вам нравятся из моих рук - я бы рекомендовал изменить третий аргумент, чтобы разделить на '/, /'. Также я считаю, что нужно переписать второе поле, а не вставлять новое поле перед ним. Довольно просто изменить 'поле' на' $ 2'. –

+0

@TomFenech Поля 'aa' по-прежнему отображаются в примере вывода. Если я не буду слеп (что, по общему признанию, не будет без прецедента), новое поле должно быть вставлено. Вещь '/, /' кажется для меня вопросом вкуса. Я полагаю, что может быть сделан аргумент, что '/, /' делает его более видимым, поскольку аргумент 'split' является регулярным выражением, но я субъективно считаю его менее читаемым. – Wintermute

+0

Ах да, вы правы в том, чтобы вставить поле. Я предполагаю, что аргумент в пользу использования регулярного выражения заключается в том, что вы спасаете бедный awk от необходимости конвертировать строку для вас, затрачивая несколько циклов :-) –

Смежные вопросы