Как мне присоединиться к двум файлам CSV, но только в том случае, где совпадает второй файл?

У меня есть 2 CSV-файла:

Объекты Файл:

IP,MASK,DESCRIPTION
10.10.3.94,255.255.255.255,Rob
10.10.3.95,255.255.255.255,Mark
10.10.3.96,255.255.255.255,John

Файл служб:

DESCRIPTION,OrgIP,Service
Rob,1.1.1.1,Purple
John,2.2.2.2,Green
Mark,3.3.3.3,Yellow

В файле объектов есть 3000 строк, файл службы имеет около 500.

Я хочу создать новый файл, который имеет все строки из служб с полями объектов, добавленными там, где найдено совпадение в описании. Таким образом, желаемый результат будет выглядеть так:

DESCRIPTION,OrgIP,Service,IP,MASK
Rob,1.1.1.1,Purple,10.10.3.94,255.255.255.255
John,2.2.2.2,Green,10.10.3.96,255.255.255.255
Mark,3.3.3.3,Yellow,10.10.3.95,255.255.255.255
1
задан 7 April 2016 в 06:09

3 ответа

Если у вас есть sqlite3 и python, установленные в вашей системе, вы можете использовать это http://www.sqlet.com/.

Соответствующей командой sql будет:

./sqlet.py -d',' -A file1.txt -B file2.txt 'select A3,B2,B3,A1,A2 from A LEFT JOIN B ON A3=B1;' | sqlite3

Для этого необходимо удалить заголовки из двух файлов. Скрипт sql должен быть извлечен в той же папке, где эти два файла соответственно изменены или изменены.

Я попробовал это в вашем примере. Он работает:

bruni@bruni-Inspiron-5547:~/Downloads$ cat file1.txt
10.10.3.94,255.255.255.255,Rob
10.10.3.95,255.255.255.255,Mark
10.10.3.96,255.255.255.255,John
bruni@bruni-Inspiron-5547:~/Downloads$ cat file2.txt
Rob,1.1.1.1,Purple
John,2.2.2.2,Green
Mark,3.3.3.3,Yellow
bruni@bruni-Inspiron-5547:~/Downloads$ ./sqlet.py -d',' -A file1.txt -B file2.txt 'select A3,B2,B3,A1,A2 from A LEFT JOIN B ON A3=B1;' | sqlite3
Rob,1.1.1.1,Purple,10.10.3.94,255.255.255.255
Mark,3.3.3.3,Yellow,10.10.3.95,255.255.255.255
John,2.2.2.2,Green,10.10.3.96,255.255.255.255
2
ответ дан 23 May 2018 в 12:21
  • 1
    +1 однако я почти уверен, что очень похожий (Python) скрипт, который в основном делает то же самое в репозиториях (использовать SQL-файлы «query "» в качестве таблиц). Не могу вспомнить имя. – kos 6 April 2016 в 18:14
  • 2
    @kos спасибо. Проверено ваше и возвратно-поступательное движение, так как оно имеет то преимущество, что не требует дополнительных установок. Единственное, что я больше знаком с синтаксисом SQL, чем awk. Я не нашел ничего подобного в репозиториях (было бы лучше, хотя) – Bruni 6 April 2016 в 19:31

Если файлы не слишком велики, как насчет awk?

$ awk -F, 'NR==FNR {a[$1]=$2 FS $3 FS $4; next} $3 in a {OFS=","; print $3,a[$3],$2}' services objects
DESCRIPTION,OrgIP,Service,IP,MASK
Rob,1.1.1.1,Purple,10.10.3.94,255.255.255.255
Mark,3.3.3.3,Yellow,10.10.3.95,255.255.255.255
John,2.2.2.2,Green,10.10.3.96,255.255.255.255
1
ответ дан 23 May 2018 в 12:21
  • 1
    Я просто попробовал это, но у меня нет выхода !? – MattyM 6 April 2016 в 17:10
  • 2
    @MattyM, так как у вас, похоже, возникают проблемы с другими предложенными методами, возможно, ваши файлы CSV имеют какую-то нераскрытую функцию (например, окончание строк в стиле Windows)? – steeldriver 6 April 2016 в 17:44
  • 3
    «все строки из сервисов с добавленными полями объектов, где найдено совпадение в описании», поэтому я думаю , что они хотят сделать, это напечатать все строки из services, даже те, совпадение в objects. – kos 6 April 2016 в 17:49
  • 4
    Спасибо @steeldriver, что вы были правильными файлами Windows, которые все испортили! – MattyM 6 April 2016 в 19:53

Вы можете сделать:

join -t, -a2 -11 -23 <(head -1 f1.txt; tail -n +2 f1.txt | \
         sort -t, -k1,1) <(head -1 f2.txt; tail -n +2 f2.txt | sort -t, -k3,3)
<() - синтаксис подстановки процесса, bash заменит его файловым дескриптором выходом команды внутри него, так как содержимое head -1 f1.txt; tail -n +2 f2.txt | sort -t, -k1,1 будет sort первый файл в первом поле из второй строки для отдыха, а первая строка добавлена ​​сверху, чтобы мы могли использовать его с join. То же самое касается f2.txt с полем sort в соответствии с тремя. join просто присоединяется к первому полю f1.txt и третью f2.txt в качестве общих полей.

Пример:

$ cat f1.txt 
DESCRIPTION,OrgIP,Service
Rob,1.1.1.1,Purple
John,2.2.2.2,Green
Mark,3.3.3.3,Yellow

$ cat f2.txt 
IP,MASK,DESCRIPTION
10.10.3.94,255.255.255.255,Rob
10.10.3.95,255.255.255.255,Mark
10.10.3.96,255.255.255.255,John

$ join -t, -11 -23 <(head -1 f1.txt; tail -n +2 f1.txt | sort -t, -k1,1) <(head -1 f2.txt; tail -n +2 f2.txt | sort -t, -k3,3)
DESCRIPTION,OrgIP,Service,IP,MASK
John,2.2.2.2,Green,10.10.3.96,255.255.255.255
Mark,3.3.3.3,Yellow,10.10.3.95,255.255.255.255
Rob,1.1.1.1,Purple,10.10.3.94,255.255.255.255
1
ответ дан 23 May 2018 в 12:21

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

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