2010-02-09 27 views
17

Tôi đang học awk và tôi gặp sự cố khi chuyển một biến cho tập lệnh VÀ sử dụng nó như một phần của mẫu tìm kiếm regex.Biến biến thành awk và sử dụng biến đó theo cụm từ thông dụng

Ví dụ này được giả tạo nhưng cho thấy xác suất của tôi.

dữ liệu của tôi là như sau:

Eddy  Smith  0600000000 1981-07-16 Los Angeles 
Frank  Smith  0611111111 1947-04-29 Chicago   
Victoria McSmith  0687654321 1982-12-16 Los Angeles 
Barbara  Smithy  0633244321 1984-06-24 Boston    
Jane  McSmithy 0612345678 1947-01-15 Chicago    
Grace  Jones  0622222222 1985-10-07 Los Angeles 
Bernard  Jones  0647658763 1988-01-01 New York   
George  Jonesy  0623428948 1983-01-01 New York   
Indiana  McJones  0698732298 1952-01-01 Miami    
Philip  McJonesy 0644238523 1954-01-01 Miami 

Tôi muốn một kịch bản awk mà tôi có thể vượt qua một biến và sau đó có kịch bản awk làm một regex cho biến. Tôi có tập lệnh này hiện được gọi là "003_search_persons.awk".

#this awk script looks for a certain name, returns firstName, lastName and City 

#print column headers 
BEGIN { 
    printf "firstName lastName City\n"; 
} 

#look for the name, print firstName, lastName and City 
$2 ~ name { 
    printf $1 " " $2 " " $5 " " $6; 
    printf "\n"; 
} 

tôi gọi là kịch bản như thế này:

awk -f 003_search_persons.awk name=Smith 003_persons.txt 

Nó trả về sau, đó là tốt.

firstName lastName City 
Eddy Smith Los Angeles 
Frank Smith Chicago 
Victoria McSmith Los Angeles 
Barbara Smithy Boston 
Jane McSmithy Chicago 

Nhưng bây giờ tôi muốn tìm một tiền tố nhất định "Mc". Tôi có thể ofcourse hardcode này, nhưng tôi muốn có một kịch bản awk đó là linh hoạt. Tôi đã viết như sau trong 003_search_persons_prefix.awk.

#this awk script looks for a certain prefix to a name, returns firstName, lastName and City 

#print column headers 
BEGIN { 
    printf "firstName lastName City\n"; 
} 

#look for the prefix, print firstName, lastName and City 
/^prefix/{ 
    printf $1 " " $2 " " $5 " " $6; 
    printf "\n"; 
} 

tôi gọi là kịch bản như thế này:

awk -f 003_search_persons_prefix.awk prefix=Mc 003_persons.txt 

Nhưng bây giờ nó tìm thấy không có hồ sơ.

Sự cố là mẫu tìm kiếm "/^prefix /". Tôi biết tôi có thể thay thế mẫu tìm kiếm đó bằng mẫu không phải regex, như trong tập lệnh đầu tiên, nhưng giả sử tôi muốn thực hiện bằng regex, vì tôi cần tiền tố thực sự ở đầu trường lastName, vì nó phải là tiền tố và tất cả ;-)

Làm cách nào để thực hiện việc này?

+2

dọn dẹp ở lối đi 5: thoát khỏi tất cả những điều khoản null (trailing dấu chấm phẩy), thay đổi printf "\ n "chỉ cần in" "và thay đổi printf $ 1" "$ 2 vv để chỉ cần in $ 1, $ 2 v.v. –

Trả lời

16

bạn có thể thử

BEGIN{ 
printf "firstName lastName City\n"; 
split(ARGV[1], n,"=") 
prefix=n[2] 
pat="^"prefix 
} 
$0 ~ pat{ 
    print "found: "$0 
} 

sản lượng này

$ awk -f test.awk name=Jane file 
firstName lastName City 
found: Jane  McSmithy 0612345678 1947-01-15 Chicago 

Nhìn vào awk documentation để biết thêm. (và đọc nó từ đầu đến cuối!)

+0

Cảm ơn, tôi sẽ kiểm tra điều này ngay. –

+4

Không có công cụ tách nào là cần thiết vì sử dụng name = Jane trong danh sách arg tạo biến có tên "name" với giá trị "Jane" để bạn có thể vừa nói 'pat ="^"name' trong FNR == 1 phần. Tuy nhiên, việc đặt biến với "-v" là thích hợp hơn, do đó bạn không phải làm việc xung quanh các biến không được điền trong phần BEGIN. –

0

cần được yêu cầu cụ thể? Tôi chắc chắn rằng nó khá có thể trong awk, nhưng tôi không biết điều đó, nếu bạn chỉ cần để có được công việc làm sau đó bạn có thể thử. không chắc chắn chính xác dấu phân cách đó là gì.

cut -d " " -f1-2,5 file | egrep '^regex' 
+0

awk là công cụ quyền lực thực hiện công việc cắt và grep được kết hợp. vì vậy có thể của nó với awk. Xem http://www.gnu.org/manual/gawk/html_node/Computed-Regexps.html#Computed-Regexps – ghostdog74

+0

Tôi quan tâm đến giải pháp awk cho việc này. Nhưng cảm ơn. –

1

Bạn có thể sử dụng tập lệnh ban đầu không thay đổi - $2 ~ name đã thực hiện tìm kiếm regex vì vậy nếu bạn gọi tập lệnh của mình bằng name=^Mc thì nó sẽ trả về tên bắt đầu bằng "Mc" . Trên thực tế đây không phải là một ví dụ tốt, kể từ Mc chỉ xuất hiện ở đầu tên - nếu bạn sử dụng name=^Smith sau đó nó sẽ tìm thấy Smiths nhưng không phải là McSmiths.

+0

Nhưng sau đó tôi sẽ phải vượt qua một regex (^ Smith) như là tham số, và cá nhân tôi nghĩ rằng đó là một chút xấu xí. –

5

Thay đổi kịch bản của bạn:

BEGIN { 
    print "firstName", "lastName", "City" 
    ORS = "\n\n" 
} 

$0 ~ "^" prefix { 
    print $1, $2, $5, $6 
} 

và gọi nó như

awk -v prefix="Mc" -f 003_search_persons.awk 003_persons.txt 
+0

Đẹp! Bí quyết '$ 0 ~"^"' là thứ tôi đang tìm kiếm. – fedorqui

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