2010-02-09 198 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

相关问题