![](https://www.howtogeek.com/wp-content/uploads/2022/08/csv-file-icon.png?width=1198&trim=1,1&bg-color=000&pad=1,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 đã xuất. Trên Linux, chúng ta có thể đọc các tệp CSV bằng các 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à một 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 gợi ý, một dấu phẩy “,
” được sử dụng để phân tách từng trường dữ liệu—hoặc giá trị—từ các nước láng giềng 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, thì hầu như ứng dụng đó sẽ luôn hỗ trợ CSV. Các tệp CSV có thể đọc được bằng con người. Bạn có thể xem bên trong chúng í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 một trường dữ liệu? Trường đó cần phải có dấu ngoặc kép “"
” quấn quanh nó. Để bao gồm dấu ngoặc kép trong 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 chương trình hoặc tập lệnh mà bạn đã viết, thì định dạng CSV có thể đơ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, thì cũng có những giải pháp mà chúng tôi có thể sử dụng cho việc đó.
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 bằng cách 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.
- tên đầu tiên: Tên của người đó.
- họ: Họ của người đó.
- chức danh công việc: chức danh công việc của người đó.
- địa chỉ email: Địa chỉ email của người đó.
- ngành: Chi nhánh công ty họ làm việc.
- tiểu bang: Bang đặt chi nhánh.
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à phần đầu của tập tin của chúng tôi:
Dòng đầu tiên chứa 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 Biểu mẫu 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 chia nhỏ nó ra.
Chúng tôi đang sử dụng một while
vòng. Miễn là while
vòng điều kiện giải quyết thành sự thật, cơ thể 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âu lệnh được sử dụng để in các 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 xác định rằng dấu phẩy sẽ được sử dụng làm dấu tách trường nội bộ, với IFS=","
tuyên bố. 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 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à ký tự bình thường.
Văn bản mà read
phân tích cú pháp 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 làm cho cuộc sống dễ dàng hơn.
Dữ liệu thu được dưới dạng đầu ra từ tail
chỉ huy. Đang sử dụng tail
bởi 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) tùy chọn cho biết tail
để bắt đầu đọc ở dòng số hai.
Các <(...)
cấu trúc được gọi là quá trình thay thế. Nó khiến Bash chấp nhận đầu ra của một quy trình như thể nó đến từ một bộ mô tả tệp. Điều này sau đó được chuyển hướng vào 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 được bằng cách sử dụng chmod
chỉ huy. 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 từng 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 ta có thể có được một lựa chọn các lĩnh vực bằng cách kết hợp các cut
chỉ huy.
Tập lệnh này có tên 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ế quá 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 trong phần thân của while
vòng.
Đây là những gì chúng tôi nhận được khi chạy tập lệnh.
./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 mà bạn xử lý không phức tạp, 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. Để hiển thị các sự cố 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 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 đặt 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ó dưới dạng “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úng tôi 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 chúng tôi.
./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 này được dịch chuyển một vị trí sang phải. Trường cuối cùng chứa cả hai 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 quanh từ “Ngân sách”.
Bản ghi thứ ba thực sự xử lý trường bị thiếu như bình thường. Địa chỉ email bị thiếu, nhưng mọi thứ khác vẫn như bình thường.
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 trường hợp 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 khó khăn và 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. Một cách tiếp cận khác—đặc biệt nếu bạn đang làm việc đến hạn chót 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 kịch bản sự cố chẳng hạn như dấu phẩy và dấu ngoặc kép được nhúng. Trình phân tích cú pháp Bash đơn giản của bạn sau đó có thể đối phó với CSV thân thiện với Bash.
Bộ công cụ csvkit
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 này:
sudo apt install csvkit
Để cài đặt nó trên Fedora, bạn cần gõ:
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ó, thì csvlook
tiện ích hiển thị một bảng hiển thị nội dung của từng trường. Nội dung trường được hiển thị để hiển thị những gì nội dung trường đại diện, chứ 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 được hiển thị chính xác. Điều này chứng tỏ vấn đề không phải do CSV. Vấn đề là 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
chỉ huy. Các -c
(cột) tùy chọn 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 ta 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 theo, 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 ta có thể đưa nó qua csvlook
.
csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook
Một điều thú vị là, mặc dù các bản ghi đã được sắp xếp, nhưng dòng tiêu đề có tên trường vẫn được giữ ở 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 một tệp CSV mới bằng cách chuyển hướng đầu ra thành một tệp.
Chúng tôi đã thêm nhiều dữ liệu hơn vào “sample2.file”, đã xóa csvsort
lệnh và tạo một tệp mới có tên là “sample3.csv.”
csvcut -c 3,2,4,5 sample2.csv > sample3.csv
Một cách an toàn để vệ sinh 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 dấu phẩy. Bạn có thể thay thế chúng bằng “không có gì” để chúng biến mất hoặc bằng một ký tự không ảnh hưởng đến quá trình 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 bên trong trường dữ liệu. Chúng được hiển thị dưới dạng dấu ngoặc đơn. 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 cá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ả cá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 là “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úng tôi 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ẽ hỗ trợ bạn rất nhiều.