Слияние двух CSV-файлов, не может избавиться от новой строки - PullRequest
0 голосов
/ 20 января 2019

Я объединяю два CSV-файла.Для простоты я показываю только соответствующие столбцы.В обоих файлах содержится более четырех столбцов.

file_a.csv

col2, col6, col7, col17
a, b, c, 145
e, f, g, 101
x, y, z, 243

file_b.csv

col2, col6, col7, col17
a, b, c, 88
e, f, g, 96
x, k, l, 222

Вывод должен выглядеть следующим образом:

col2, col6, col7, col17, col18
a, b, c, 145, 88
e, f, g, 101, 96

Таким образом, col17 из file_b добавляется в file_a как col18, когда содержимое col2, col6 и col7 совпадает.

Я пробовал это:

awk -F, 'NR == FNR {a[$2,$6,$7] = $17;next;} {if (! (b = a[$2,$6,$7])) b = "N/A";print $0,FS,b;}' file_a.csv file_b.csv > out.csv

Вывод выглядит так:

col2, col6, col7, col17, 
 , col18
a, b, c, 145
 , 88
e, f, g, 101
 , 96

Итак, столбец 17 из file_b, который я пытаюсь добавить, добавляется, но отображается в новой строке.

Я думаю, это потому, что после каждой строки есть возврат каретки.из file_a и file_b.В Notepad ++ я вижу CRLF.Но я не могу от них избавиться.Кроме того, я бы предпочел не проходить два этапа: сначала избавиться от возврата каретки, а затем слить.Вместо этого, если я смогу обойти возврат каретки во время слияния, это будет намного быстрее.

Кроме того, я буду признателен, если вы скажете мне, как избавиться от пробелов до и после запятой, разделяющейобъединенная колонка.Обратите внимание, что я помещаю пробелы между столбцами и запятыми для других столбцов для лучшей читаемости.Это не так, как в реальных файлах.Но в объединенном файле действительно есть пробелы между col17 и "," и col18, и я не знаю почему.

Если вы настаиваете на том, чтобы пометить это как дубликат, пожалуйста, объясните в комментарии ниже, как ответына предыдущий вопрос (ы) решить мою проблему.Я попытался выяснить это по тем же предыдущим вопросам, но потерпел неудачу.

Ответы [ 4 ]

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

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

Ответ предполагает, что в файлах \r.Я использовал опцию -vT для cat, чтобы показать, что возврат каретки существует

$ cat -vT file_a.csv
col2, col6, col7, col17^M
a, b, c, 145^M
e, f, g, 101^M
x, y, z, 243^M
$ cat -vT file_b.csv
col2, col6, col7, col17^M
a, b, c, 88^M
e, f, g, 96^M
x, k, l, 222^M
$

$ perl -lne  'BEGIN { %kv=map{chomp;chop;@a=split(/\s*,\s*/);"$a[0],$a[1],$a[2]"=>"$a[3]"} qx(cat file_b.csv) } chop;@b=split(/\s*,\s*/);$x="$b[0],$b[1],$b[2]"; print "$x,$b[-1],",$kv{$x} if $kv{$x} ' file_a.csv
col2,col6,col7,col17,col17
a,b,c,145,88
e,f,g,101,96
$
0 голосов
/ 20 января 2019

Не могли бы вы попробовать следующее.

awk -v RS="[\r\n]+" '
BEGIN{
  SUBSEP=OFS=", "
}
FNR==NR{
  if(FNR==1){
    header=$0
  }
  a[$1,$2,$3]=$4
  next
}
FNR==1 && FNR!=NR{
  split(header,array,", ")
  sub(/[a-zA-Z]+/,"",array[4])
  print header,"col"array[4]+1
  next
}
a[$1,$2,$3]{
  print $0,a[$1,$2,$3]
}' b.csv a.csv

Что делает вышеуказанный код:

1- Похоже, вы можете получить возврат кареткив ваших файлах Input_file, поэтому я сделал \r\n в качестве разделителя записей (в случае, если вы хотите удалить возврат каретки, попробуйте tr -d '\r < a.csv > temp && mv temp a.csv и тоже для других полей).

2 - Это создаст заголовоктакже согласно последнему столбцу вашего файла.

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

с Миллером (http://johnkerl.org/miller/doc)

mlr --csv join -j col2,col6,col7 --lp l --rp r -f file_a.csv \
then unsparsify --fill-with "" \
then rename lcol17,col17,rcol17,col18 file_b.csv

у вас есть

col2,col6,col7,col17,col18
a,b,c,145,88
e,f,g,101,96

Я использовал в качестве ввода

# file_a.csv

col2,col6,col7,col17
a,b,c,145
e,f,g,101
x,y,z,243

# file_b.csv

col2,col6,col7,col17
a,b,c,88
e,f,g,96
x,k,l,222
0 голосов
/ 20 января 2019

Попробуйте, пожалуйста (GNU awk):

awk -F, -v RS="[\r\n]+" 'NR == FNR {a[$2,$6,$7] = $17;next;} {b=a[$2,$6,$7]; print $0 FS (b? b : "N/A")}' file_a.csv file_b.csv 

Проблема, с которой у вас возникли проблемы:
1. Возврат каретки, RS="[\r\n]+", будет обрабатывать несколько новых строк, включая \rи \n в качестве разделителей строк.Обратите внимание, что при этом также будут игнорироваться пустые строки, если вы не хотите, измените на RS="\r\n".
2. Пробелы, потому что по умолчанию в awk OFS это пробел.И когда вы печатаете, вы использовали ,, это добавит пробелы между ними.Просто используйте пробел или когда-нибудь просто напишите их вместе, они будут объединены.

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