将两个 .csv 文件合并为一个并仅保留一个标头 - 在 bash 中

问题描述 投票:0回答:4

我在同一目录中有两个具有相同列数的 .csv 文件,我想将它们组合成一个文件,但只保留第一个文件中的一个标题。文件名总是不同的,只有前缀保持不变:

orderline_123456.csv

Order_number,Quantity,Price
100,10,25.3
101,15,30.2

orderline_896524.csv

Order_number,Quantity,Price
102,20,12.33
103,3,3.4

输出文件应如下所示:

file_load.csv

Order_number,Quantity,Price
100,10,25.3
101,15,30.2
102,20,12.33
103,3,3.4

这已经在 shell 脚本文件中了,因为现在我只需要获取一个文件,但现在我必须合并两个文件:

awk '(NR-1)%2{$1=$1}1' RS=\" ORS=\" orderline_*.csv >> file_to_load.csv

我尝试将其更改为

awk 'FNR == 1 && NR != 1 {next} (NR-1)%2{$1=$1}1' RS=\" ORS=\" orderline_*.csv >> file_to_load.csv

但是我在输出中得到了两次标题。

你能帮我一下吗?该命令到底应该是什么样子?我需要保留它之前的定义方式。

谢谢!

bash unix
4个回答
5
投票

您正在寻找

awk 'NR == 1 || FNR > 1' file ...

NR 是查看的所有记录的计数,并且
FNR 是当前文件的记录号。


1
投票

有时解决方案是将任务分成简单的步骤

1.获取第一行,即标题并存储为变量

https://stackoverflow.com/a/2439587/3957754

header=$(head -n 1 file1.csv)

2.获取文件中除第一行之外的所有行

如何尾随除第一行之外的所有行

body=$(tail -n+2 file1.csv)

对两个文件重复此操作

3.连接 header 和 n 个 body

csv_merger.sh

header=$(head -n 1 file1.csv)
body1=$(tail -n+2 file1.csv)
body2=$(tail -n+2 file2.csv)
echo "$header" > merged.csv
echo "$body1" >> merged.csv
echo "$body2" >> merged.csv

结果

您可以扩展此脚本以处理更多文件


0
投票

使用方便的 csvkit 包中的

csvstack 是合并具有相同列的 CSV 文件的一种方法:

$ csvstack orderline_123456.csv orderline_896524.csv > file_load.csv
    

0
投票
使用

cp

 用第一个文件填充输出文件。使用 
grep
 忽略仅从第二个文件中删除标头并与 
>>
 连接。

cp orderline_123456.csv file_load.csv grep -v Order orderline_896524.csv >> file_load.csv
一般来说,通过在任一文件上使用 

head -n 1

 询问第 1 行,可以轻松地自动处理任何可能的标头。

© www.soinside.com 2019 - 2024. All rights reserved.