2011-12-25 26 views
48

Cho một tập tin với dữ liệu như thế này (ví dụ: stores.dat tập tin)unix - đếm các cột trong file

sid|storeNo|latitude|longitude 
2|1|-28.03720000|153.42921670 
9|2|-33.85090000|151.03274200 

Điều gì sẽ là một lệnh để ra số lượng tên cột?

tức Trong ví dụ trên nó sẽ là 4. (số ký tự ống + 1 trong dòng đầu tiên)

Tôi đã suy nghĩ cái gì đó như:

awk '{ FS = "|" } ; { print NF}' stores.dat 

nhưng nó sẽ trả về tất cả các dòng thay vì chỉ số đầu tiên và dòng đầu tiên trả về 1 thay vì 4

Trả lời

76
awk -F'|' '{print NF; exit}' stores.dat 

Chỉ cần thoát ngay sau dòng đầu tiên.

+1

hoặc 'awk -F' | ' 'NR == 1 {print NF}' stores.dat' –

+10

@JaypalSingh: sẽ đọc toàn bộ tệp - không cần điều đó, hãy dừng sớm hơn. – Mat

+0

Cả hai dường như trả lại cùng một ouput chính xác, là có bất kỳ lợi ích hiệu suất của 1 trên khác (hoặc một số lợi ích khác)? – toop

9

Trừ khi bạn đang sử dụng dấu cách trong đó, bạn sẽ có thể sử dụng | wc -w trên dòng đầu tiên.

wc là "Số từ", chỉ đơn giản đếm các từ trong tệp đầu vào. Nếu bạn chỉ gửi một dòng, nó sẽ cho bạn biết số cột.

+0

Tôi đã thử: head -1 stores.dat | wc -w Nhưng điều đó không trả về những gì tôi sau – toop

+0

Đó là vì bạn không thay thế '|' bằng một dấu cách - 'wc' sẽ đếm các từ, mà phải được phân cách bằng dấu cách. Sử dụng 'head -1 stores.dat | tr '|' '' | wc -w' –

+2

Vui lòng thêm nhận xét của bạn vào câu trả lời vì mục đích hoàn chỉnh. – Xofo

28

Đây là một cách giải quyết (đối với tôi: Tôi không sử dụng awk rất thường xuyên):

hiển thị dòng đầu tiên của file chứa dữ liệu, thay thế tất cả ống với dòng mới và sau đó đếm dòng:

$ head -1 stores.dat | tr '|' '\n' | wc -l 
+6

Đối với các tệp có maaany cột (nghĩ rằng dữ liệu SNP) đây là cách để đi. Giải pháp của Mat trả về "awk: vượt quá giới hạn chương trình: số lượng trường tối đa kích thước = 32767". –

1

Nếu bạn đã python cài đặt bạn có thể thử:

python -c 'import sys;f=open(sys.argv[1]);print len(f.readline().split("|"))' \ 
    stores.dat 
+0

trong trường hợp cụ thể này, nó ngắn hơn để đọc từ đầu vào chuẩn 'cat x.txt | python -c "print raw_input(). count ('|') + 1" ' –

+0

ngắn hơn có, nhưng không nhanh hơn, nếu có nhiều tập tin dài! Tôi cho rằng anh ta muốn một giải pháp nhanh hơn trong con mắt của các tệp dữ liệu thuần túy (có nghĩa là lớn). –

1

này thường là những gì tôi sử dụng cho đếm số lượng các lĩnh vực:

head -n 1 file.name | awk -F'|' '{print NF; exit}' 
4

Bạn có thể thử

mèo FILE | awk '{print NF}'

1

giải pháp Perl tương tự như giải pháp awk Mat của:

perl -F'\|' -lane 'print $#F+1; exit' stores.dat 

Tôi đã thử nghiệm này trên một tập tin với 1000000 cột.


Nếu tách lĩnh vực là khoảng trắng (một hoặc nhiều khoảng trắng hoặc tab) thay vì một ống:

perl -lane 'print $#F+1; exit' stores.dat 
0

Dựa trên Cát Kerr phản ứng. Lệnh này đang làm việc trên solaris

awk '{print NF; exit}' stores.dat 
+0

Và sau đó bạn đang ở câu trả lời được chấp nhận trừ đi dấu phân cách trường thích hợp. Điều này sẽ trả về "1" cho đầu vào ví dụ. –

+0

Điều này về bản chất giống như câu trả lời được chấp nhận mà không có dấu tách trường, như Bejamin nói trả về 1 nhưng nên làm việc cho các tệp phân tách không gian. – discipulus

0

bạn có thể thử:

head -1 stores.dat | grep -o \| | wc -l 
0

chọn bất kỳ hàng trong tập tin (trong ví dụ dưới đây, đó là hàng thứ 2) và đếm số lượng các cột, nơi dấu phân tách là khoảng trắng:

sed -n 2p text_file.dat | tr ' ' '\n' | wc -l 
Các vấn đề liên quan