Вопрос по csv, linux, vlookup, bash, compare – Найти значение из одного csv в другом (например, vlookup) в bash (Linux)

0

Я уже перепробовал все варианты, которые я нашел в Интернете, чтобы решить мою проблему, но без хорошего результата.

В основном у меня есть два CSV-файла (разделенных трубами):

file1.csv:

123 | 21 | 0452 | IE | IE | 1 | MAYOBAN | BRIN | ОФИС | УЛИЦА | ОСНОВНАЯ УЛИЦА | MAYOBAN |

123 | 21 | 0453 | IE | IE | 1 | CORKKIN | РОБЕРТ | ФАМИЛИЯ | ПРОБКА | APTS | CORKKIN |

123 | 21 | 0452 | IE | IE | 1 | CORKCOR | NAME | HARRINGTON | Дублин | STREET | CORKCOR |

file2.csv:

MAYOBAN | BANGOR | 2400

MAYOBEL | Беллавэри | 2400

CORKKIN | Кинсэйл | 2200

CORKCOR | ПРОБКА | 2200

DUBLD11 | ДУБЛИН 11 | 2100

Мне нужен скрипт bash для Linux, чтобы найти значение pos.3 из file2 на основе содержимого pos7 в file1.

Пример: file1, line1, pos 7: MAYOBAN найти MAYOBAN в файле 2, вернуть позицию 3 (2400)

вывод должен быть примерно таким:

2400

2200

2200

etc...

Пожалуйста помоги Яцек

разбить на массивы и проверить, возможно, дубликаты. Не уверен, что это способ сделать это, но это моя первая мысль. keyser

Ваш Ответ

3   ответа
2

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

join -t '|' -1 7 -2 1 -o 2.3 <(sort -t '|' -k7,7 file1.csv) <(sort -t '|' -k1,1 file2.csv)

Вывод будет выглядеть так:

2200
2200
2400

который бесполезен. Чтобы получить полезный вывод, включите значение ключа:

join -t '|' -1 7 -2 1 -o 0,2.3 <(sort -t '|' -k7,7 file1.csv) <(sort -t '|' -k1,1 file2.csv)

Выходные данные выглядят так:

CORKCOR|2200
CORKKIN|2200
MAYOBAN|2400

Edit:

Вот версия AWK:

awk -F '|' 'FNR == NR {keys[$7]; next} {if ($1 in keys) print $3}' file1.csv file2.csv

Это перебирает файл file1.csv и создает записи массива для каждого значения поля 7. Простая ссылка на элемент массива создает его (с нулевым значением).FNR номер записи в текущем файле иNR номер записи во всех файлах. Когда они равны, первый файл обрабатывается.next Инструкция читает следующую запись, создавая цикл. когдаFNR == NR больше не верно, последующие файлы обрабатываются.

Таким образом, file2.csv теперь обрабатывается, и если у него есть поле 1, которое существует в массиве, то его поле 3 печатается.

@Yasapl: я добавил версию AWK в свой ответ. Если вы нашли мой ответ полезным, отметьте его как одобренный и проголосуйте за него. Благодарю.
Большой! Это работает как шарм. На самом деле первый вариант подходит, так как мне не нужна сортировка. Выходные данные используются для статистических целей, поэтому, если суммы в порядке, это нормально. Я пробовал AWK, но без хороших результатов. Yasapl
0
cut -d\| -f7 file1.csv|while read line
do 
  grep $line file1.csv|cut -d\| -f3
done
5

Небольшой подход, далеко, чтобы быть идеальным:

DELIMITER="|"

for i in $(cut -f 7 -d "${DELIMITER}" file1.csv ); 
do 
    grep "${i}" file2.csv | cut -f 3 -d "${DELIMITER}"; 
done
@DennisWilliamson: Спасибо, что просветил меня.
ОтWikipedia: "каждая запись состоит из полей, разделенных каким-либо другим символом или строкой, обычно литеральной запятой или табуляцией." и "при обычном использовании почти любые разделенные разделителем текстовые данные могут упоминаться как" CSV "; . Файл & Quot;

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