2013-04-12 45 views
24

Nếu tôi muốn chuyển tham số vào tệp tập lệnh awk, tôi có thể làm như thế nào?Truyền tham số vào tệp tập lệnh awk

#!/usr/bin/awk -f 

{print $1} 

Ở đây tôi muốn in đối số đầu tiên truyền cho các kịch bản từ vỏ, như:

bash-prompt> echo "test" | ./myawkscript.awk hello 
bash-prompt> hello 
+2

comlete awk tutotial [có sẵn] (http://www.gnu.org/software/gawk/manual/gawk.html#Invoking- Gawk) – jhonnash

Trả lời

15

nổ băm của bạn xác định kịch bản không phải là shell script, nó là một kịch bản awk. bạn không thể làm điều đó theo cách bash trong kịch bản của bạn.

cũng vậy, những gì bạn đã làm: echo blah|awk ...không truyền tham số, nó sẽ đưa đầu ra của lệnh echo sang lệnh khác.

bạn có thể thử những cách dưới đây:

echo "hello"|./foo.awk file - 

hoặc

var="hello" 
awk -v a="$var" -f foo.awk file 

với điều này, bạn có var a trong foo.awk của bạn, bạn có thể sử dụng nó.

nếu bạn muốn làm điều gì đó giống như tập lệnh shell chấp nhận $ 1 $ 2 vars, bạn có thể viết một shellscript nhỏ để bọc những thứ awk của bạn.

EDIT

Không, tôi không hiểu lầm bạn.

chúng ta hãy lấy ví dụ:

giả, x.awk của bạn có:

{print $1} 

nếu bạn làm:

echo "foo" | x.awk file 

nó là giống như:

echo "foo"| awk '{print $1}' file 

ở đây đầu vào cho awk chỉ là file, echo của bạn không có ý nghĩa.nếu bạn làm:

echo "foo"|awk '{print $1}' file - 
or 
    echo "foo"|awk '{print $1}' - file 

awk mất hai đầu vào (lập luận cho awk) một là stdin là một trong những tập tin, trong kịch bản awk của bạn, bạn có thể:

echo "foo"|awk 'NR==FNR{print $1;next}{print $1}' - file 

này sẽ in đầu tiên foo từ tiếng vang của bạn , sau đó cột1 từ file tất nhiên ví dụ này không có tác dụng gì, chỉ cần in tất cả.

nhiên bạn có thể có nhiều hơn hai đầu vào, và không kiểm tra NR và FNR, bạn có thể sử dụng

ARGC The number of elements in the ARGV array. 

ARGV An array of command line arguments, excluding options and the program argument, numbered from zero to ARGC-1 

ví dụ:

echo "foo"|./x.awk file1 - file2 

sau đó bạn "foo" là arg thứ 2, bạn có thể lấy nó trong x.awk của bạn bằng cách ARGV[2]

echo "foo" |x.awk file1 file2 file2 - 

bây giờ là ARGV [4].

Ý tôi là, echo "foo"|.. của bạn sẽ là stdin cho awk, nó có thể bởi 1 hoặc thứ n "đối số"/đầu vào cho awk. phụ thuộc vào nơi bạn đặt - (stdin). Bạn phải xử lý nó trong kịch bản awk của bạn.

+1

Bạn có hiểu lầm, bạn hiểu rằng echo blah | awk ... có nghĩa là tôi đang đi tham số để kịch bản awk. Đọc lại. –

+1

bình luận upvoted tốt đẹp :) .. @UNIX xem chỉnh sửa, tôi hy vọng nó sẽ bị xóa ngay bây giờ. – Kent

+0

@UNIX trong thời gian ngắn, nếu bạn muốn tệp 'echo foo | ./x.awk' của bạn in' foo' trước, hãy làm 'echo foo | ./x.awk - file' – Kent

13

Bạn có thể sử dụng -v như một command-line option để cung cấp một biến để kịch bản:

Giả sử chúng tôi có một tập tin script.awk như thế này:

BEGIN {print "I got the var:", my_var} 

Sau đó chúng ta chạy nó như thế này:

$ awk -v my_var="hello this is me" -f script.awk 
I got the var: hello this is me 
+1

IMO, đây là câu trả lời duy nhất thực sự giải quyết được câu hỏi. Để thêm vào điều này, bạn vẫn có thể thực hiện việc này nếu tập lệnh của bạn có thể thực thi: 'tệp cat | script.awk -v my_var = "hello this is you" ' – xdhmoore

35

Trong awk$1 tham chiếu trường đầu tiên trong bản ghi không phải là điểm đầu tiên giống như trong bash. Bạn cần sử dụng ARGV để làm điều này, hãy xem here cho từ chính thức.

Script:

#!/bin/awk -f 

BEGIN{ 
    print "AWK Script" 
    print ARGV[1] 
} 

Demo:

$ ./script.awk "Passed in using ARGV" 
AWK Script 
Passed in using ARGV 
+2

Cách tốt hơn được chấp nhận, súc tích và chính xác. – cdosborn

+0

POSIX 7 cũng vậy: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html –

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