合并两个 csv 文件,无法摆脱换行符

Merging two csv files, can't get rid of newline

我正在合并两个 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

因此当 col2、col6 和 col7 的内容匹配时,file_b 的 col17 添加到 file_a 作为 col18。

我试过这个:

awk -F, 'NR == FNR {a[,,] = ;next;} {if (! (b = a[,,])) b = "N/A";print [=13=],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

所以我尝试添加的 file_b 中的第 17 列确实已添加,但显示在新行上。

我想这是因为file_a和file_b每行后面都有回车returns。在 Notepad++ 中,我可以看到 CRLF。但我无法摆脱它们。另外,我宁愿不经历两个步骤:首先摆脱运输 returns 然后合并。相反,如果我可以在合并过程中绕过马车returns,它会快得多。

此外,如果您能告诉我如何去掉分隔合并列的逗号前后的空格,我将不胜感激。请注意,为了更好的可读性,我在列之间放置了空格,在其他列中放置了逗号。这不是它在实际文件中的样子。但是合并后的文件中col17和","以及col18之间确实有空格,不知道为什么。

如果您坚持将此标记为重复,请在下面的评论中解释上一个问题的答案如何解决我的问题。我试着从之前的类似问题中找出答案,但我失败了。

请试试这个(GNU awk):

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

您遇到的问题:
1、回车returns,通过RS="[\r\n]+",会把多个换行,包括\r\n作为行分隔符。请注意,这也会忽略空行,如果您不想,请更改为 RS="\r\n".
2. spaces,那是因为awk默认的OFS是一个space。当您打印时,您使用了 ,,这将在它们之间添加 space。只需使用 space 或有时将它们写在一起即可,它们将被连接起来。

能否请您尝试以下。

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

以上代码的作用:

1- 好像你的 Input_file(s) 中可能有回车 returns 所以我将 \r\n 作为记录分隔符(如果你想删除回车 returns 然后尝试 tr -d '\r < a.csv > temp && mv temp a.csv 并为其他领域也做)。

2- 这也会根据您文件的最后一列创建 header。

与米勒 (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

因为你想在分隔符 , 之间获取空格,你可以尝试这个 Perl 解决方案,它在拆分时删除空格。

答案假定您在文件中有 \r。我为 cat 使用了 -vT 选项来表明 return 存在

$ 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
$