Trích xuất dữ liệu từ một tệp và đặt vào các tệp khác nhau dựa trên một giá trị cột


13

Chúng tôi sẽ tạo một tệp csv với các giá trị dưới đây

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Tôi cần trích xuất dữ liệu và tạo tập tin dựa trên cột thứ hai. Nếu là 577 thì toàn bộ dòng phải được trích xuất và đặt trong một tệp riêng. Ý tôi là tôi cần một tệp có các dòng có cột thứ hai là 577 và một tệp khác có cột thứ hai là 132

Tôi đã thử sử dụng IF nhưng không hiệu quả


5
Trên thực tế, việc đăng mã không hoạt động luôn là một ý tưởng tốt.
goldilocks

Câu trả lời:


26

Sử dụng awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Điều này sẽ tạo ra hai tập tin 577.csv132.csvtrong thư mục hiện tại của bạn.

Lệnh trên giả định rằng bạn chỉ có thể có 132hoặc 577là trường thứ hai. Nó sẽ tạo một tên tệp cho mỗi giá trị được tìm thấy trong trường thứ hai của toàn bộ file.csv.

Nếu có các giá trị khác ngoài hai giá trị bạn quan tâm và bạn muốn bỏ qua các dòng đó, thay vào đó, hãy thực hiện điều này:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv

1
Có những awktriển khai lỗi không thể sử dụng print > $2 ".cvs". Trên đó, trước tiên bạn phải tính toán tên tệp, sau đó thực hiện print: fname = $2 ".cvs"; print > fname.
Kusalananda

3

Tôi thích awkgiải pháp của terdon , nhưng để hoàn thiện, đây là một gợi ý chỉ sử dụngbash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Nó sẽ tạo ra các tập tin 577.csv132.csvtrong thư mục hiện tại.


3

Để trích xuất tất cả 577 vào thiết bị xuất chuẩn

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- chỉnh sửa 1 Đã sửa, dựa trên nhận xét của @ terdon bên dưới để tránh kết quả sai khi có ít nhất 3 dấu phẩy trên dòng với 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Nhưng tôi nghĩ awkgiải pháp của anh ấy / cô ấy toàn diện hơn.


Điều đó sẽ phù hợp ngay cả khi 577 nằm trên một lĩnh vực khác, không phải thứ hai hoặc nếu đó là một phần của một lĩnh vực. Ví dụ foo577barhay yp9012,132,8,577.
terdon

Tôi nghĩ dấu phẩy của tôi sẽ làm cho nó phụ thuộc vào vị trí trường?
X Tian

Xin lỗi, tôi đã đưa ra các ví dụ xấu nhưng .*cũng có thể khớp dấu phẩy để bạn không biết bạn phù hợp với lĩnh vực nào. Có thể là thứ hai, cũng có thể là thứ 45. Khiếu nại thứ hai của tôi là sai, bạn đúng là dấu phẩy bảo vệ khỏi khớp foo577bar.
terdon

Phải làm gì nếu | ký tự được sử dụng thay vì ,.
dùng3116123

nhận được lỗi bên dưới grep: tùy chọn bất hợp pháp - e Cách sử dụng: tệp mẫu grep -hblcnsviw. . .
dùng3116123

1

Sử dụng csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

Các -c 2làm cho cvsgrepxem xét cột thứ hai, và với -m 577chúng tôi yêu cầu nó để phù hợp với chuỗi 577trong cột đó.

Sau đây sẽ được viết vào output.csv:

yp1234,577,1,3
yp5678,577,3,5

Để khớp một số chuỗi và ghi đầu ra vào một tệp cho mỗi chuỗi:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Điều này sẽ tạo ra hai tập tin output-132.csvoutput-577.csv.

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.