2010-02-09 210 views
17

我正在學習awk,並且無法將變量傳遞給腳本並將其用作正則表達式搜索模式的一部分。將變量傳遞給awk並在正則表達式中使用它

這個例子是人爲的,但顯示我的探頭。

我的數據是這樣的:

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 

我想awk腳本,我可以傳遞一個變量,然後讓awk腳本做一個正則表達式的變量。 我有這個腳本現在叫做「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"; 
} 

我所說的腳本是這樣的:

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

它返回以下,這是很好的。

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

但是現在我想尋找一個特定的前綴「Mc」。我當然可以硬編碼,但我想要一個靈活的awk腳本。我在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"; 
} 

我這樣調用腳本:

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

但現在它找到任何記錄。

問題是搜索模式「/^prefix /」。我知道我可以用一個非正則表達式替換搜索模式,就像在第一個腳本中一樣,但是假設我想用正則表達式來完成,因爲我需要前綴真正處於lastName字段的開頭,因爲它應該是,作爲前綴和所有;-)

我該怎麼做?

+2

清理:擺脫所有的空語句(尾隨分號),變化的printf「的\ n 「來簡單地打印」「,並將printf $ 1」「$ 2等改爲簡單地打印$ 1,$ 2等。 – 2012-11-13 18:12:30

回答

16

你可以試試這個

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

輸出

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

看那awk documentation更多。 (並從頭到尾讀取它!)

+0

謝謝,我會盡快測試。 – 2010-02-09 09:52:06

+4

沒有一個分割的東西是必要的,因爲在arg列表中使用name = Jane創建一個名爲「name」的值爲「Jane」的變量,因此您可以在FNR == 1中說出'pat =「^」name「部分。無論如何設置變量「-v」是可取的,儘管如此,您不必在BEGIN部分中填充變量。 – 2012-11-13 18:22:18

0

是awk特別需要的嗎?我相信在awk中這是完全可能的,但我不知道,如果你只需要完成工作,那麼你可以嘗試。不確定究竟是什麼分隔符。

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

awk是一個能夠完成cut和grep工作的電源工具。所以是的,它可能與awk。請參閱http://www.gnu.org/manual/gawk/html_node/Computed-Regexps.html#Computed-Regexps – ghostdog74 2010-02-09 08:22:09

+0

我對這個awk解決方案感興趣。但是,謝謝。 – 2010-02-09 09:50:14

1

您應該可以使用原始腳本不變 - $2 ~ name已經在執行正則表達式搜索,因此如果您使用name=^Mc調用腳本,則它將返回以「Mc」開頭的名稱, 。其實這不是一個好例子,因爲Mc只出現在名字的開頭 - 如果你使用name=^Smith那麼它會找到Smiths而不是McSmiths。

+0

但是,我將不得不通過正則表達式(^ Smith)作爲參數,並且我個人認爲這有點難看。 – 2010-02-09 09:57:48

5

你的腳本改爲:

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

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

,並在過道5稱其爲

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

美麗! '$ 0〜'^「'技巧就是我所要找的。 – fedorqui 2015-10-28 14:23:49

相關問題