Hợp nhất nhiều tệp CSV mà không hợp nhất tiêu đề


20

Tôi cần hợp nhất nhiều tệp .CSV (sử dụng catlệnh) nhưng không sao chép tiêu đề cho mỗi tệp.

Cách tốt nhất để hoàn thành nhiệm vụ này là gì?

Câu trả lời:


32

Bạn sẽ cần nhiều hơn catlệnh, như được mô tả ở đây :

Giả sử bạn có 3 CSV-files: file1.csv, file2.csv, và file3.csvvà muốn tham gia cùng họ để bigfile.csvvà tiêu đề của bạn luôn luôn là (chỉ) dòng đầu tiên, sau đó sử dụng

hoặc (giữ tiêu đề từ tệp đầu tiên "file1.csv"):

cat file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv

hoặc (xóa tiêu đề khỏi tất cả các tệp mà tên của chúng bắt đầu bằng "tệp"):

awk 'FNR > 1' file*.csv > bigfile.csv

4
Tôi thấy điều này đang tìm kiếm một câu trả lời chung chung cho linux, nhưng trong trường hợp của tôi thì nó không hoạt động chính xác. Nó sẽ âm thầm bỏ qua file1.csv. Tôi cần phải cat tập tin đó. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
Lelon

Tôi không nhận được lệnh tail + 2: khi tôi sử dụng cat <file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv)> phương thức bigfile.csv

@ user64636 có phải là một nhân vật không gian giữa đuôi và 2
nohillside

thực ra tôi phải sử dụng tail -n+2, tail +2sẽ không hiệu quả
Matthieu Napoli

11

Tôi đồng ý với câu trả lời hàng đầu nhưng tôi đề nghị mở rộng nó với kịch bản sau (vì tôi không thể nhận xét):

Nếu bạn muốn tệp đầu ra chứa tiêu đề (một lần) thì tập lệnh chính xác là:

awk '(NR == 1) || (FNR > 1)' file*.csv > bigfile.csv

FNR đại diện cho số lượng bản ghi được xử lý trong một tệp. Và NR đại diện cho nó trên toàn cầu, vì vậy dòng đầu tiên được chấp nhận và phần còn lại bị bỏ qua như trước.


6

Bạn cũng có thể sử dụng lệnh nhóm ( { ; }) thay vì quá trình thay thế ( <()):

{ head -n1 file1.csv; for f in file*.csv; do tail -n+2 "$f"; done; } > new.csv

Nó cũng hoạt động với các kết thúc dòng CRLF miễn là các tệp kết thúc bằng một dòng trống ( \r\n).

Các phiên bản đầu và đuôi chỉ có số đã bị lỗi thời bởi POSIX 1003.1-2001 và chúng dẫn đến cảnh báo trong một số môi trường.


2

Cần ghép hai CSV lớn với các cột giống hệt nhau thành CSV lớn hơn để tạo đoạn mã (dữ liệu không có id duy nhất).

Đầu tiên lấy tiêu đề ra khỏi csv thứ hai

awk 'FNR > 1' file2.csv > file2_noheading.csv

Tiếp theo, nối thông qua như sau

cat file1.csv file2_noheading.csv > newfile.csv

1

Sử dụng chuỗi lệnh trên dẫn đến một tệp trông như thế này:

header,of,csv1
contents,of,csv1
==> csv2.csv

contents,of,csv2

Để biến nó thành một CSV thích hợp, với một dòng tiêu đề và tất cả các giá trị có liên quan, tôi đã sử dụng sedcâu thần chú sau đây ...sed -ie "/^$/d;/^==>/d" bigfile.csv


0

Giải pháp dễ dàng hơn nếu bạn có rất nhiều tệp:

awk 'FNR > 1' *.csv > merged.csv

Chỉ cần quay lại để chỉnh sửa tệp lớn và thêm tiêu đề trở lại.


Làm thế nào là câu trả lời của bạn khác với những gì đã được iolsmit trình bày vào năm 2013 awk 'FNR > 1' file*.csv > bigfile.csv? Nó không thể!
dùng3439894

Re: nó khác nhau như thế nào? Đó là một câu trả lời ngắn gọn hơn và là câu trả lời mà tôi đã sao chép và dán, ít nhất là :) Nhận được sự ủng hộ của tôi
Rick Davies

Đây là một câu trả lời hay, bởi vì bạn không cần tất cả các tệp để bắt đầufile
big_smile
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.