Я пытаюсь объединить два файла csv с помощью AWK. Если 1-й столбец в файле 1 соответствует 1-му столбцу в файле 2, я хочу изменить 3-й столбец файла 1 на значение 2-го столбца файла 2. Если совпадения нет, не вносите изменений и переходите к следующей строке.

File1.csv

alice,soccer,24
bob,baseball,21
jessica,swimming,22
mike,running,20

File2.csv

alice,5
jessica,9

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

alice,soccer,5
bob,baseball,21
jessica,swimming,9
mike,running,20

Мой код на данный момент:

#!/bin/bash

    awk -F"," 'BEGIN{OFS=","}
        { if (NR==NFR){ 
         array[$1]=$1; 
        } 
        if ( $1 in array ){
         $3=array[$2]
        }
         print
        }' file2.csv file1.csv
2
tortor11 7 Июл 2020 в 21:26
1
Не array[$1]=$1, а array[$1]=$2 -- это фактически захватит данные в файле2.
 – 
glenn jackman
7 Июл 2020 в 22:23

1 ответ

Лучший ответ

Пытаться:

$ awk -F, 'FNR==NR{a[$1]=$2;next} $1 in a{$3=a[$1]} 1' OFS=, file2.csv file1.csv
alice,soccer,5
bob,baseball,21
jessica,swimming,9
mike,running,20

Как это работает

  • -F,

    Это устанавливает разделитель полей ввода на запятую.

  • FNR==NR{a[$1]=$2;next}

    При чтении file2.csv это сохраняет второе поле под ключом первого поля в массиве a.

    Обратите внимание на использование next. Это говорит awk пропустить остальные команды и начать заново со следующей строки.

    Например, после чтения вашего file2.csv содержимое массива a будет следующим: a['alice']=5 и a['jessica']=9.

  • $1 in a{$3=a[$1]}

    При чтении file1.csv, если первое поле существует как ключ в массиве a, это обновляет третье поле до значения, хранящегося в a.

    Тест $1 in a верен, если содержимое $1 (которое мы читаем из file1.csv) является одним из ключей (а не одним из значений) массив a.

  • 1

    Это сокращение для {print}.

  • OFS=,

    Это устанавливает разделитель выходных полей в виде запятой.

2
John1024 7 Июл 2020 в 22:27
Спасибо, что сделал работу! :) Есть одна вещь, которую я никак не могу понять. FNR==NR{a[$1]=$2;next} будет содержать 5,9 или что именно будет содержать массив a? Если он содержит 5,9, проверка $1 in a{$3=a[$1]} не имеет для меня смысла. Можете ли вы уточнить?
 – 
tortor11
7 Июл 2020 в 22:21
1
После чтения file2.csv содержимое массива a будет следующим: a['alice']=5 и a['jessica']=9. Тест $1 in a верен, если содержимое $1 является одним из ключей (а не одним из значений) массива a.
 – 
John1024
7 Июл 2020 в 22:24
1
"если содержимое $1 в файле1"
 – 
glenn jackman
7 Июл 2020 в 22:25
1
Спасибо, это прояснило!
 – 
tortor11
7 Июл 2020 в 22:57