Проверьте, присутствует ли список шаблонов из file1.csv в file2.csv и измените записи в file2.csv - PullRequest
0 голосов
/ 17 января 2019

У меня есть 2 файла file1.csv и file2.csv

file1.csv содержит только 1 столбец с сотнями строк.

aaa
ddd
fff
ggg

file2.csv содержит 5 полей с тысячами строк.

aaa,2,3,4,
aaa,2,3,4, 
bbb,2,3,4,
ccc,2,3,4, 
ccc,2,3,4, 
ddd,2,3,4, 
ddd,2,3,4,
ddd,2,3,4,  
eee,2,3,4, 
fff,2,3,4, 
ggg,2,3,4, 
hhh,2,3,4, 
hhh,2,3,4,   

Моя задача - проверить, совпадает ли col1, присутствующий в file1.csv, с col1 в fil2.csv, затем изменить 5-й столбец на Y в file2.csv

Желаемый вывод

aaa,2,3,4,Y
aaa,2,3,4,Y 
bbb,2,3,4, 
ccc,2,3,4, 
ccc,2,3,4, 
ddd,2,3,4,Y
ddd,2,3,4,Y
ddd,2,3,4,Y  
eee,2,3,4, 
fff,2,3,4,Y 
ggg,2,3,4,Y 
hhh,2,3,4, 
hhh,2,3,4, 

я попробовал

for i in $(cat file1.csv); do awk -F "," '$1==$i{$5="Y"}1' OFS="," file2.csv ; done

Но я получаю только сопоставленные записи, но не сопоставленные записи.

Есть ли лучший способ, которым я могу достичь этого в UNIX, используя awk, sed или другие распространенные утилиты.

EDIT: Обновить вопрос на понятном примере

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Вы можете попробовать решение Perl

$ perl -F, -lane 'BEGIN {%kv=map{chomp;$_=>1} qx(cat file1.csv) } print "$_", $kv{$F[0]}? "Y" : "" ' file2.csv
aaa,2,3,4,Y
aaa,2,3,4,Y
bbb,2,3,4,
ccc,2,3,4,
ccc,2,3,4,
ddd,2,3,4,Y
ddd,2,3,4,Y
ddd,2,3,4,Y
eee,2,3,4,
fff,2,3,4,Y
ggg,2,3,4,Y
hhh,2,3,4,
hhh,2,3,4,

$ cat file1.csv
aaa
ddd
fff
ggg

$ cat file2.csv
aaa,2,3,4,
aaa,2,3,4,
bbb,2,3,4,
ccc,2,3,4,
ccc,2,3,4,
ddd,2,3,4,
ddd,2,3,4,
ddd,2,3,4,
eee,2,3,4,
fff,2,3,4,
ggg,2,3,4,
hhh,2,3,4,
hhh,2,3,4,

$
0 голосов
/ 17 января 2019

Не нужно так делать, просто awk читает два файла, это нормально:

awk -F, 'NR==FNR{a[$1]++;next;}a[$1]{$5="Y"}1' file1.csv file2.csv

Не уверены, что заголовок и вторая строка - это ваш способ объяснения, если вы хотите избавиться от них:

awk -F, 'NR==FNR{a[$1]++;next;}a[$1]{$5="Y"}FNR>2' file1.csv file2.csv

Обратите внимание, что если file1.csv может быть пустым, вы должны изменить NR==FNR на другие методы проверки файлов, например ARGIND==1 для GNU awk или FILENAME=="file1.csv" и т. Д.

Если вам нужно иметь дело с огромными данными, измените a[$1]++ на a[$1]=1, что немного улучшит скорость.
Также, если вы хотите сохранить заголовок (или 2-ю строку), то лучше начинать изменять массив a, когда FNR>1 или FNR>2. Совершенствуйте команду самостоятельно, я уверен, что вы поняли;)

NR==FNR означает первый файл, потому что NR означает N общее количество R записей сейчас, а FNR означает текущий F файл N число R записей.
a - это массив для сохранения $1 в качестве ключей.
next пропустить выполнение другого блока.

Если NR==FNR имеет значение false, это означает, что это не первый файл, первый блок не будет выполнен.
(Вы также можете использовать NR>FNR перед блоком, чтобы указать его, но так как я использовал next в NR==FNR блоке, то в этом нет необходимости.)
Затем запускаются другие директивы, a[$1] - чтобы судить, существует ли ключ в массиве a или нет (по значению, буквально проверьте, key exists на самом деле должно быть $1 in a), если он существует, то измените $ 5.
Последний 1 должен указывать истинное значение, это ярлык для {print}.
(Поскольку выражение без блока будет подразумевать {print}, и блок будет выполнен, когда вышеприведенное выражение рассчитано как true, для которого 1 всегда истинно.)

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