2012-05-30 36 views
11

Thỉnh thoảng tôi nhận được tệp CSV có trả về vận chuyển bên trong ô. Đây không phải là một định dạng có thể chấp nhận được đối với một chương trình sẽ sử dụng nó làm đầu vào.Đếm dấu phẩy trong một dòng trong bash

Để phát hiện xem dòng đầu vào có bị tách hay không, tôi đã xác định rằng một dòng không hợp lệ sẽ không có số lượng dấu phẩy được mong đợi trong đó. Có bash hoặc công cụ dòng lệnh unix chung nào khác có cho phép tôi đếm dấu phẩy trong dòng không? Nếu cần thiết, tôi có thể viết một chương trình Python hoặc Perl để làm điều đó, nhưng nếu có thể, tôi muốn thêm một hoặc hai dòng vào một tập lệnh bash hiện có để làm cho nó thất bại nếu số lượng dấu phẩy là sai. Ý tưởng nào?

+1

Tại sao bạn không thể tìm kiếm các khoản trả lại vận chuyển và xóa chúng? –

+1

Tôi giả sử người hỏi có nghĩa là ngắt dòng nói chung và "chỉ xóa chúng" sẽ không hoạt động, vì các dòng hợp lệ cũng kết thúc bằng một ký tự cấp dữ liệu dòng. – lanzz

+8

'a, b," c, d, e "' có 3 trường nhưng 4 dấu phẩy – Stefan

Trả lời

29

Strip tất cả mọi thứ nhưng dấu phẩy, và sau đó đếm số ký tự còn lại:

$ echo foo,bar,baz | tr -cd , | wc -c 
2 
5

Để đếm số lần một dấu phẩy xuất hiện, bạn có thể sử dụng một cái gì đó giống như awk:

string=(line of input from CSV file) 
echo "$string" | awk -F "," '{print NF-1}' 

Nhưng điều này thực sự không đủ để xác định liệu một trường có trả về vận chuyển trong trường đó hay không. Các trường có thể có dấu phẩy bên trong miễn là chúng được bao quanh bởi dấu ngoặc kép.

-2

Chỉ cần loại bỏ tất cả các kí tự xuống dòng:

tr -d "\r" old_file > new_file 
+1

Tại sao hàm ý lại? –

+0

downvote vì trả về vận chuyển là hợp lệ nếu nó phân định các bản ghi trong tệp, vì vậy chúng không thể bị xóa. –

2

Hãy thử Perl:

$ perl -ne 'print [email protected]{[/,/g]},"\n"' 
a 
0 
a,a 
1 
a,a,a,a,a 
4 
+1

Bạn có thể ép nó vào một vô hướng dễ dàng hơn bằng cách nối thêm dòng mới: 'print @ {[/,/g]}. "\ n" ' –

+1

Sử dụng perl là ... một lựa chọn thú vị. Nếu tôi định sử dụng perl, tôi nghĩ rằng tôi sẽ đi với: 'perl -F, -anE' nói $ # F''. Nhưng đây là một giải pháp mới ... nên +1! –

+0

@WilliamPursell +2 để trở thành Hướng dẫn Perl ;-) – ceving

4

Trong Bash tinh khiết:

while IFS=, read -ra array 
do 
    echo "$((${#array[@]} - 1))" 
done < inputfile 

hoặc

while read -r line 
do 
    count=${line//[^,]} 
    echo "${#count}" 
done < inputfile 
0

Tùy thuộc vào những gì bạn đang cố gắng làm với dữ liệu CSV, có thể hữu ích khi sử dụng tập lệnh trình bao bọc như csvquote để tạm thời thay thế các dòng mới có vấn đề (và dấu phẩy) bên trong các trường được trích dẫn, sau đó khôi phục chúng. Ví dụ:

csvquote inputfile.csv | wc -l 

csvquote inputfile.csv | cut -d, -f1 | csvquote -u 

có thể là loại điều bạn đang tìm kiếm. Xem [https://github.com/dbro/csvquote][1] để biết mã và biết thêm thông tin

Các vấn đề liên quan