2012-02-19 40 views
38

Lệnh nàyLàm thế nào tôi có thể nhận được độ dài của một mảng trong awk?

echo "hello world" | awk '{split($0, array, " ")} END{print length(array) }' 

không làm việc cho tôi và đưa ra thông báo lỗi này

awk: dòng 1: tài liệu tham khảo bất hợp pháp để mảng mảng

Tại sao?

+1

Trên thực tế, mã của bạn làm việc cho tôi và trả về 2 như mong đợi. –

+2

Nó hoạt động với 'gawk' nhưng không phải POSIX' awk' hoặc 'gawk --posix'. – nwk

Trả lời

71

Khi bạn chia một mảng, số phần tử được trả lại, vì vậy bạn có thể nói:

echo "hello world" | awk '{n=split($0, array, " ")} END{print n }' 
# ------------------------^^^--------------------------------^^ 

Output là:

2 
0
echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }' 
14

Chỉ muốn chỉ rằng:

  • Không cần lưu trữ kết quả của split chức năng để in nó.
  • Nếu dấu phân tách không được cung cấp cho phần tách, mặc định FS (khoảng trống) sẽ được sử dụng.
  • Phần ENDvô ích tại đây.

    echo 'hello world' | awk '{print split($0, a)}' 
    
2

mẫu trên MacOSX Lion để hiển thị các cổng được sử dụng (đầu ra có thể 192.168.111.130.49704 hoặc :: 1,49704):

netstat -a -n -p tcp | awk '/\.[0-9]+/{n=split($4,a,"."); print a[n]}' 

Trong ví dụ này, đó in các mục mảng cuối cùng của cột thứ 4: "49704"

18

Tôi không nghĩ người đó đang hỏi "Làm cách nào để chia chuỗi và nhận độ dài của mảng kết quả?" Tôi nghĩ rằng lệnh họ cung cấp chỉ là một ví dụ về tình huống mà nó xuất hiện. Đặc biệt, tôi nghĩ người đó đang hỏi 1) Tại sao length(array) kích hoạt lỗi và 2) Làm thế nào tôi có thể nhận được độ dài của một mảng trong awk?

Câu trả lời cho câu hỏi đầu tiên là chức năng độ dài không hoạt động trên các mảng trong tiêu chuẩn POSIX, mặc dù nó có trong GNU awk (gawk) và một vài biến thể khác. Câu trả lời cho câu hỏi thứ hai là (nếu chúng ta muốn một giải pháp hoạt động trong tất cả các biến thể của awk) để thực hiện quét tuyến tính.

Ví dụ, một hàm như thế này

function alen (a, i) { 
    for (i in a) 
    return i 
} 

LƯU Ý: Tham số thứ hai i bảo đảm một số lời giải thích.

Cách bạn giới thiệu biến cục bộ trong awk là tham số hàm bổ sung và quy ước là chỉ ra điều này bằng cách thêm khoảng trống thừa trước các tham số này. Đây là được thảo luận trong số GNU Awk manual.

+2

điểm tốt. Mục đích của tôi là trả lời câu hỏi ban đầu bằng các thuật ngữ của O.P. 'awk '{split ($ 0, array," ")} ...'', và do đó câu trả lời của tôi, được lấy từ việc sử dụng 'split' trong bản gốc 'The Awk Programming Language'. Chúc mọi người may mắn. – shellter

+0

Cảm ơn. Tôi không có ý định trả lời của tôi để được như vậy pithy. Tôi đã có một chút vội vàng. Có lẽ tôi sẽ làm mềm nó một chút. –

+0

Nhưng tất cả điều này là trả về chỉ mục đầu tiên của một mảng? Ngoài ra, thứ tự của mảng lặp không được chỉ định bởi POSIX. – Spookbuster

28

Mr.Chức năng của Ventimiglia đòi hỏi một chút điều chỉnh để thực hiện công việc (xem dấu chấm phẩy trong câu lệnh):

function alen(a, i) { 
    for(i in a); 
    return i 
} 

Nhưng không làm việc tất cả các trường hợp hoặc thời gian. Đó là bởi vì cách thức mà awk lưu trữ và "xem" các chỉ mục của mảng: chúng là liên kết và không nhất thiết phải tiếp giáp (như C.) Vì vậy, i không trả lại phần tử "cuối cùng".

Để giải quyết nó, bạn cần phải đếm:

function alen(a, i, k) { 
    k = 0 
    for(i in a) k++ 
    return k 
} 

Và, theo cách này, chăm sóc các loại chỉ số khác của mảng "unidimensional", nơi mà các chỉ số có thể là một chuỗi. Vui lòng xem: http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm. Đối với mảng "đa chiều" và tùy ý, hãy xem http://www.gnu.org/software/gawk/manual/html_node/Walking-Arrays.html#Walking-Arrays.

4

Trong gawk bạn có thể sử dụng chức năng length():

$ gawk 'BEGIN{a[1]=1; a[2]=2; a[23]=45; print length(a)}' 
3 

$ gawk 'BEGIN{a[1]=1; a[2]=2; print length(a); a[23]=45; print length(a)}' 
2 
3 

Từ The GNU Awk user's guide:

Với gawk và một số triển khai awk khác, khi đưa ra một lập luận mảng, các length() chức năng trả về số các phần tử trong mảng . (c.e.) Điều này ít hữu ích hơn so với lúc đầu có vẻ như, chẳng hạn như mảng không được đảm bảo được lập chỉ mục từ một đến số lượng các phần tử trong đó. Nếu --lint được cung cấp trên dòng lệnh (xem Tùy chọn), gawk cảnh báo rằng việc truyền tham số mảng không thể di chuyển được. Nếu --posix được cung cấp, sử dụng đối số mảng là một lỗi nghiêm trọng (xem Mảng).

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