[ad_1]
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:
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
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
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
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
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ả branch
và state
các giá trị.
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”.
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.
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 nó trên Fedora, bạn cần nhập:
sudo dnf install python3-csvkit
Trên Manjaro, lệnh là:
sudo pacman -S csvkit
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
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ú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
Để 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
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.
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.
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
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
[ad_2]