Найдите соответствие в файле CSV

У меня есть два файла CSV.

1.csv содержит:

46700468915;2000

2.csv содержит:

4670046;Tele2

Я пробую к поиску от 2.csv, если 4670046 существует в 1.csv, который является, делает и затем берут от 2.csv Tele2 и включают 1.csv, если никакое соответствие не добавляет

awk 'NR==FNR {a[$1]=$2; next} $2 in a {print $0, a[$2]}' OFS='\t' 2.csv 1.csv
0
задан 27 February 2020 в 16:01

2 ответа

У Вас есть несколько проблем здесь:

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

  2. Вы пытаетесь соответствовать на частичном поле: 4670046 находится в a но 46700468915 не

  3. Вы, кажется, смущены, о котором поле Вы соответствуете, $1 или $2

Если Вы знаете, что хотите соответствовать первым 7 символам, можно попробовать

awk -F ';' '
  NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}
' OFS='\t' 2.csv 1.csv

или эквивалентно

awk '
  BEGIN{FS=";"; OFS="\t"} 
  NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}
' 2.csv 1.csv

Напр. данный

$ head ?.csv
==> 1.csv <==
46700468915;2000

==> 2.csv <==
4670046;Tele2

затем

$ awk 'BEGIN{FS=";"; OFS="\t"} NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}' 2.csv 1.csv
46700468915;2000    Tele2
1
ответ дан 27 February 2020 в 23:35

awk решение должно быть намного быстрее, но здесь является примером, как достигнуть этого через bash сценарий, который read каждая строка 2.csv как -array и затем использует sed сделать изменения ( if оператор не является основной частью сценария).

$ cat ./script.sh
#!/bin/bash

TARGET_FILE="./1.csv"
ORIGIN_FILE="./2.csv"

# In order to append new column to a line, comment-out -i.bak
while IFS=';' read -r -a line
do
        if grep -q "${line[0]}" "$TARGET_FILE"
        then
                sed "/^${line[0]}/ s/$/;${line[1]}/" "$TARGET_FILE" #-i.bak
        fi
done < "$ORIGIN_FILE"

echo '-----'

# In order to replace the second column of a line, comment-out -i.bak
while IFS=';' read -r -a line
do
        if grep -q "${line[0]}" "$TARGET_FILE"
        then
                sed -r "s/(^${line[0]}.*\;).*$/\1${line[1]}/" "$TARGET_FILE" #-i.bak
        fi
done < "$ORIGIN_FILE"

Пример использования:

$ cat 1.csv
46700468915;2000
46700568916;3000
46700668917;4000

$ cat 2.csv
4670046;Tele2
4670047;Tele3
4670048;Tele4

$ ./script.sh
46700468915;2000;Tele2
46700568916;3000
46700668917;4000
-----
46700468915;Tele2
46700568916;3000
46700668917;4000
0
ответ дан 27 February 2020 в 23:35

Другие вопросы по тегам:

Похожие вопросы: