Cách phân tích cú pháp dữ liệu CSV trong Bash

[ad_1]

Sửa máy tính tại nhà TPHCM

Jane Kelly / Shutterstock.com

Các tệp Giá trị được Phân tách bằng Dấu phẩy (CSV) là một trong những định dạng phổ biến nhất cho dữ liệu được xuất. Trên Linux, chúng ta có thể đọc tệp CSV bằng lệnh Bash. Nhưng nó có thể trở nên rất phức tạp, rất nhanh chóng. Chúng tôi sẽ giúp một tay.

Tệp CSV là gì?

Tệp Giá trị được Phân tách bằng Dấu phẩy là tệp văn bản chứa dữ liệu được lập bảng. CSV là một loại dữ liệu được phân tách. Như tên cho thấy, dấu phẩy “,”Được sử dụng để tách từng trường dữ liệu — hoặc giá trị—Từ những người hàng xóm của nó.

CSV ở khắp mọi nơi. Nếu một ứng dụng có chức năng nhập và xuất, ứng dụng đó hầu như sẽ luôn hỗ trợ CSV. Các tệp CSV có thể đọc được. Bạn có thể nhìn vào bên trong chúng với ít hơn, mở chúng trong bất kỳ trình soạn thảo văn bản nào và di chuyển chúng từ chương trình này sang chương trình khác. Ví dụ: bạn có thể xuất dữ liệu từ cơ sở dữ liệu SQLite và mở nó trong LibreOffice Calc.

Tuy nhiên, ngay cả CSV cũng có thể trở nên phức tạp. Bạn muốn có dấu phẩy trong trường dữ liệu? Trường đó cần có dấu ngoặc kép “"”Quấn quanh nó. Để đưa dấu ngoặc kép vào một trường, mỗi dấu ngoặc kép cần được nhập hai lần.

Tất nhiên, nếu bạn đang làm việc với CSV được tạo bởi một chương trình hoặc tập lệnh mà bạn đã viết, thì định dạng CSV có thể sẽ đơn giản và dễ hiểu. Nếu bạn buộc phải làm việc với các định dạng CSV phức tạp hơn, với Linux là Linux, chúng tôi cũng có thể sử dụng các giải pháp cho điều đó.

Một số dữ liệu mẫu

Bạn có thể dễ dàng tạo một số dữ liệu CSV mẫu, sử dụng các trang web như Trình tạo dữ liệu trực tuyến. Bạn có thể xác định các trường bạn muốn và chọn số lượng hàng dữ liệu bạn muốn. Dữ liệu của bạn được tạo bằng các giá trị giả thực tế và được tải xuống máy tính của bạn.

Chúng tôi đã tạo một tệp chứa 50 hàng thông tin nhân viên giả:

  • Tôi: Một giá trị số nguyên duy nhất đơn giản.
  • họ: Tên của người.
  • họ: Họ của người.
  • chức vụ: Chức danh công việc của người đó.
  • địa chỉ email: Địa chỉ email của người đó.
  • chi nhánh: Chi nhánh công ty mà họ làm việc.
  • tiểu bang: Trạng thái mà chi nhánh đặt tại.

Một số tệp CSV có dòng tiêu đề liệt kê tên trường. Tệp mẫu của chúng tôi có một. Đây là đầu tệp của chúng tôi:

Tệp CSV mẫu

Dòng đầu tiên chứa các tên trường dưới dạng các giá trị được phân tách bằng dấu phẩy.

Phân tích cú pháp dữ liệu Tạo thành tệp CSV

Hãy viết một tập lệnh sẽ đọc tệp CSV và trích xuất các trường từ mỗi bản ghi. Sao chép tập lệnh này vào trình chỉnh sửa và lưu vào tệp có tên “field.sh”.

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample.csv)

Có khá nhiều thứ được đóng gói trong kịch bản nhỏ của chúng tôi. Hãy phá vỡ nó.

Chúng tôi đang sử dụng một while vòng. Miễn là while vòng tình trạng phân giải thành true, phần thân của while vòng lặp sẽ được thực hiện. Phần thân của vòng lặp khá đơn giản. Một bộ sưu tập của echo các câu lệnh được sử dụng để in giá trị của một số biến vào cửa sổ đầu cuối.

Các while điều kiện vòng lặp thú vị hơn phần thân của vòng lặp. Chúng tôi chỉ định rằng dấu phẩy nên được sử dụng làm dấu phân tách trường nội bộ, với IFS="," bản tường trình. IFS là một biến môi trường. Các read lệnh đề cập đến giá trị của nó khi phân tích cú pháp các chuỗi văn bản.

Chúng tôi đang sử dụng read lệnh của -r (giữ lại dấu gạch chéo ngược) để bỏ qua bất kỳ dấu gạch chéo ngược nào có thể có trong dữ liệu. Họ sẽ được coi là các ký tự thông thường.

Văn bản mà read các phân tích lệnh được lưu trữ trong một tập hợp các biến được đặt tên theo các trường CSV. Họ có thể dễ dàng được đặt tên field1, field2, ... field7 nhưng những cái tên có ý nghĩa giúp cuộc sống dễ dàng hơn.

Dữ liệu thu được dưới dạng đầu ra từ tail yêu cầu. Đang sử dụng tail vì nó cung cấp cho chúng tôi một cách đơn giản để bỏ qua dòng tiêu đề của tệp CSV. Các -n +2 (số dòng) cho biết tail để bắt đầu đọc ở dòng số hai.

Các <(...) cấu trúc được gọi là thay thế quy trình. Nó khiến Bash chấp nhận đầu ra của một quá trình như thể nó đến từ một bộ mô tả tệp. Điều này sau đó được chuyển hướng đến while vòng lặp, cung cấp văn bản mà read lệnh sẽ phân tích cú pháp.

Làm cho tập lệnh có thể thực thi bằng cách sử dụng chmod yêu cầu. Bạn sẽ cần thực hiện việc này mỗi khi sao chép tập lệnh từ bài viết này. Thay thế tên của tập lệnh thích hợp trong mỗi trường hợp.

chmod +x field.sh

Tạo một tập lệnh có thể thực thi được với chmod

Khi chúng tôi chạy tập lệnh, các bản ghi được phân chia chính xác thành các trường cấu thành của chúng, với mỗi trường được lưu trữ trong một biến khác nhau.

./field.sh

Tệp CSV được phân tích cú pháp bởi tập lệnh field.sh.

Mỗi bản ghi được in dưới dạng một tập hợp các trường.

Chọn trường

Có lẽ chúng ta không muốn hoặc không cần truy xuất mọi trường. Chúng tôi có thể có được lựa chọn các trường bằng cách kết hợp cut yêu cầu.

Tập lệnh này được gọi là “select.sh”.

#!/bin/bash

while IFS="," read -r id jobtitle branch state
do
  echo "Record ID: $id"
  echo "Job Title: $jobtitle"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)

Chúng tôi đã thêm cut lệnh vào mệnh đề thay thế quy trình. Chúng tôi đang sử dụng -d (dấu phân cách) tùy chọn để nói cut sử dụng dấu phẩy “,”Làm dấu phân cách. Các -f (trường) tùy chọn cho biết cut chúng tôi muốn các trường một, bốn, sáu và bảy. Bốn trường đó được đọc thành bốn biến, được in ra trong phần nội dung của while vòng.

Đây là những gì chúng ta nhận được khi chạy script.

./select.sh

Phân tích cú pháp tệp CSV với field.sh để trích xuất một lựa chọn trường cụ thể

Bằng cách thêm cut lệnh, chúng tôi có thể chọn các trường chúng tôi muốn và bỏ qua những trường chúng tôi không muốn.

Càng xa càng tốt. Nhưng mà…

Nếu CSV bạn xử lý không phức tạp mà không có dấu phẩy hoặc dấu ngoặc kép trong dữ liệu trường, thì những gì chúng tôi đã đề cập có thể sẽ đáp ứng nhu cầu phân tích cú pháp CSV của bạn. Để chỉ ra những vấn đề mà chúng tôi có thể gặp phải, chúng tôi đã sửa đổi một mẫu dữ liệu nhỏ để trông giống như thế này.

id,firstname,lastname,job-title,email-address,branch,state
1,Rosalyn,Brennan,"Steward, Senior",Rosalyn_Brennan4351@mafthy.com,Minneapolis,Maryland
2,Danny,Redden,"Analyst ""Budget""",Danny_Redden1443@brety.org,Venice,North Carolina
3,Lexi,Roscoe,Pharmacist,,Irlington,Vermont
  • Bản ghi một có dấu phẩy trong job-title trường, vì vậy trường cần được đặt trong dấu ngoặc kép.
  • Bản ghi hai có một từ được bao bọc trong hai bộ dấu ngoặc kép trong jobs-title đồng ruộng.
  • Bản ghi ba không có dữ liệu trong email-address đồng ruộng.

Dữ liệu này đã được lưu dưới dạng “sample2.csv.” Sửa đổi tập lệnh “field.sh” của bạn để gọi “sample2.csv” và lưu nó thành “field2.sh”.

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample2.csv)

Khi chạy tập lệnh này, chúng tôi có thể thấy các vết nứt xuất hiện trong trình phân tích cú pháp CSV đơn giản của mình.

./field2.sh

Chạy field2.sh

Bản ghi đầu tiên chia trường chức danh công việc thành hai trường, coi phần thứ hai là địa chỉ email. Mỗi trường sau khi này được dịch chuyển một chỗ sang bên phải. Trường cuối cùng chứa cả branchstate các giá trị.

Một bản ghi có một trường được chia thành hai trường

Bản ghi thứ hai giữ lại tất cả các dấu ngoặc kép. Nó chỉ nên có một cặp dấu ngoặc kép xung quanh từ “Ngân sách”.

Một bản ghi có dấu ngoặc kép được xử lý sai

Bản ghi thứ ba thực sự xử lý trường bị thiếu như nó cần. Địa chỉ email bị thiếu, nhưng mọi thứ khác vẫn như vậy.

Bản ghi có trường bị thiếu, được xử lý chính xác

Ngược lại, đối với một định dạng dữ liệu đơn giản, rất khó để viết một trình phân tích cú pháp CSV dạng chữ hoa chung mạnh mẽ. Các công cụ như awk sẽ cho phép bạn đến gần, nhưng luôn có những trường hợp cạnh và trường hợp ngoại lệ lọt qua.

Cố gắng viết một trình phân tích cú pháp CSV không thể sai lầm có lẽ không phải là cách tốt nhất về phía trước. Một cách tiếp cận thay thế — đặc biệt nếu bạn đang làm việc đến một thời hạn nào đó — sử dụng hai chiến lược khác nhau.

Một là sử dụng một công cụ được thiết kế có mục đích để thao tác và trích xuất dữ liệu của bạn. Thứ hai là làm sạch dữ liệu của bạn và thay thế các tình huống có vấn đề như dấu phẩy và dấu ngoặc kép được nhúng. Sau đó, trình phân tích cú pháp Bash đơn giản của bạn có thể đối phó với CSV thân thiện với Bash.

Bộ công cụ CSV csvkit là một tập hợp các tiện ích được tạo rõ ràng để giúp làm việc với các tệp CSV. Bạn sẽ cần cài đặt nó trên máy tính của mình.

Để cài đặt nó trên Ubuntu, hãy sử dụng lệnh sau:

sudo apt install csvkit

Cài đặt csvkit trên Ubuntu

Để cài đặt nó trên Fedora, bạn cần nhập:

sudo dnf install python3-csvkit

Cài đặt csvkit trên Fedora

Trên Manjaro, lệnh là:

sudo pacman -S csvkit

Cài đặt csvkit trên Manjaro

Nếu chúng tôi chuyển tên của tệp CSV cho nó, csvlook tiện ích hiển thị một bảng hiển thị nội dung của mỗi trường. Nội dung trường được hiển thị để cho biết nội dung trường đại diện, không phải khi chúng được lưu trữ trong tệp CSV.

Hãy thử csvlook với tệp “sample2.csv” có vấn đề của chúng tôi.

csvlook sample2.csv

CSV rắc rối được phân tích cú pháp chính xác bởi csvlook

Tất cả các trường đều được hiển thị chính xác. Điều này chứng tỏ vấn đề không phải là CSV. Vấn đề là các tập lệnh của chúng tôi quá đơn giản để diễn giải CSV một cách chính xác.

Để chọn các cột cụ thể, hãy sử dụng csvcut yêu cầu. Các -c (cột) có thể được sử dụng với tên trường hoặc số cột hoặc kết hợp cả hai.

Giả sử chúng ta cần trích xuất họ và tên, chức danh công việc và địa chỉ email từ mỗi bản ghi, nhưng chúng ta muốn có thứ tự tên là “họ, tên”. Tất cả những gì chúng ta cần làm là đặt tên trường hoặc số theo thứ tự chúng ta muốn.

Ba lệnh này đều tương đương nhau.

csvcut -c lastname,firstname,job-title,email-address sample2.csv
csvcut -c lastname,firstname,4,5 sample2.csv
csvcut -c 3,2,4,5 sample2.csv

Chọn các trường theo thứ tự ưu tiên với csvcut

Chúng tôi có thể thêm csvsort lệnh sắp xếp đầu ra theo một trường. Chúng tôi đang sử dụng -c (cột) tùy chọn để chỉ định cột để sắp xếp và -r (đảo ngược) tùy chọn để sắp xếp theo thứ tự giảm dần.

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r

Chọn các trường và sắp xếp chúng theo một cột duy nhất

Để làm cho đầu ra đẹp hơn, chúng tôi có thể cung cấp cho nó thông qua csvlook .

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook

Sử dụng csvlook để in đẹp lựa chọn các trường đã được sắp xếp

Một điểm nhấn rõ ràng là, ngay cả khi các bản ghi được sắp xếp, dòng tiêu đề với tên trường vẫn được giữ như dòng đầu tiên. Khi chúng tôi hài lòng, chúng tôi có dữ liệu theo cách chúng tôi muốn, chúng tôi có thể xóa csvlook từ chuỗi lệnh và tạo tệp CSV mới bằng cách chuyển hướng đầu ra thành tệp.

Chúng tôi đã thêm nhiều dữ liệu hơn vào “sample2.file”, xóa csvsort và tạo một tệp mới có tên “sample3.csv.”

csvcut -c 3,2,4,5 sample2.csv > sample3.csv

Một cách an toàn để dọn dẹp dữ liệu CSV

Nếu bạn mở tệp CSV trong LibreOffice Calc, mỗi trường sẽ được đặt trong một ô. Bạn có thể sử dụng chức năng tìm và thay thế để tìm kiếm dấu phẩy. Bạn có thể thay thế chúng bằng “nothing” để chúng biến mất hoặc bằng một ký tự không ảnh hưởng đến phân tích cú pháp CSV, chẳng hạn như dấu chấm phẩy “;” Ví dụ.

Bạn sẽ không thấy dấu ngoặc kép xung quanh các trường được trích dẫn. Dấu ngoặc kép duy nhất bạn sẽ thấy là dấu ngoặc kép được nhúng nội bộ trường dữ liệu. Chúng được hiển thị dưới dạng dấu ngoặc kép. Tìm và thay thế chúng bằng một dấu nháy đơn “'”Sẽ thay thế dấu ngoặc kép trong tệp CSV.

Sử dụng LibreOffice Calc's find and Replace để thay thế dấu ngoặc kép bằng dấu nháy đơn

Thực hiện tìm và thay thế trong một ứng dụng như LibreOffice Calc có nghĩa là bạn không thể vô tình xóa bất kỳ dấu phẩy phân tách trường nào, cũng như xóa dấu ngoặc kép xung quanh các trường được trích dẫn. Bạn sẽ chỉ thay đổi giá trị dữ liệu của các lĩnh vực.

Chúng tôi đã thay đổi tất cả dấu phẩy trong các trường có dấu chấm phẩy và tất cả các dấu ngoặc kép được nhúng bằng dấu nháy đơn và lưu các thay đổi của chúng tôi.

Tệp CSV đã sửa đổi

Sau đó, chúng tôi tạo một tập lệnh có tên “field3.sh” để phân tích cú pháp “sample3.csv”.

#! /bin/bash

while IFS="," read -r lastname firstname jobtitle email
do
  echo " Lastname: $lastname"
  echo "Firstname: $firstname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo ""
done < <(tail -n +2 sample3.csv)

Hãy xem những gì chúng tôi nhận được khi chạy nó.

./field3.sh

Một phần của CSV được phân tích cú pháp chính xác

Trình phân tích cú pháp đơn giản của chúng tôi hiện có thể xử lý các bản ghi có vấn đề trước đây của chúng tôi.

Bạn sẽ thấy rất nhiều CSV

CSV được cho là thứ gần nhất với ngôn ngữ chung cho dữ liệu ứng dụng. Hầu hết các ứng dụng xử lý một số dạng dữ liệu đều hỗ trợ nhập và xuất CSV. Biết cách xử lý CSV — một cách thực tế và thiết thực — sẽ giúp bạn đứng vững.

CÓ LIÊN QUAN: 9 ví dụ về Bash Script giúp bạn bắt đầu trên Linux

dịch vụ cài win online từ xa

[ad_2]

Vui lòng đánh giá về dịch vụ tại nhà