2016-01-10 51 views
0

我有一个充满线条的文件,我想用特定的格式捕捉线条,使用awk。Awk与特定格式的捕捉线

输入

text that I dont want 
control similar text but not quite 
control "1text, numbers 2 and special characters inside quotes %&¤" sometext sometext #-- The desired line 
more text I dont want 
stuff 

输出

control "text inside quotes" sometext sometext 
#-- There isn't comments like these in the file, so no need to process them 

该生产线将被存储与行号的数组里面:MENU[POS'$POS']=$0","NR

这是我已经尝试过:

awk '$0 ~ /^control "[:alpha:]" [:alpha:] [:alpha:]$/ {print}' 
awk '$0 ~ /^control "*" * *$/ {print}' 
+0

为什么不选择“控制”类似的文字“但不完全”? – SMA

+0

'awk'$ 0〜/^control“[a-z] +”[a-z] + [a-z] + $/{print}'' –

回答

3

首先,命名的字符类不能单独使用。它需要括在括号内。否则它将被解释为字符类别[:alph],这意味着文字字符:,a,l,ph

变化:

[:alpha:] 

到:

[[:alpha:]] 

其次,它看起来像你错过了[[:alpha:]]字符类后+量词。 +表示一个或多个。此外,您还应该在引号之间匹配空格。 (因为它们出现在测试数据中)。

它应该是:

awk '/^control "[[:alpha:][:space:]]+" [[:alpha:]]+ [[:alpha:]]+$/' 

这可能是缩短为:

awk '/^control "[[:alpha:][:space:]]+"([[:alpha:]]+){2}$/' 

顺便说一句,你看,你不需要在awk$0 ~ /REGEX/{print}。您可以简单地使用/REGEX/来代替。这是因为默认情况下,整个记录($0)将在awk中进行模式匹配。另外printawk中的默认操作,即如果条件评估为true且未指定操作,则awk将打印整个记录。

+0

谢谢! :DI不知道你需要那些 – BonBon

+1

你应该允许引号内的空格 –

+2

更确切地说,当你写'[:alpha:]'时,它是一个普通的字符类,其中包含字符'a','h', l','p'和':'在其中 - 不是元类(名为字符类);就像你说的那样,[[:alpha:]]'。 –

0

基于乔纳森·莱弗勒的评论:

awk '$0 ~ /^control "[^"]+"[^"]*$/ { print }' 

输出

控制 “文本中的引号” sometext sometext

这看起来与控制和双引号线,拒绝那些带有1个,3个或更多引号的人。

+1

您的'$ 2'匹配查找'零或更多双引号,然后双引号'。它看起来好像你在考虑shell式的globbing,其中'*'本身与零个或多个字符匹配。鉴于'$ 2'必须包含开始报价,但'$ 4'包含匹配的结束报价,您的错误是偶然的。我认为你应该用'awk'$ 1 ==“control”&& $ 0〜/“[^”] +“/ {print}''来寻找一对双引号,你可以把它改为: 'awk'/^control“[^”] +“[^”] * $ /''如果你只想要包含两个双引号的控制行(拒绝那些带有1或3的引号) –

+0

@JonathanLeffler谢谢,是的,这个是我第一天使用awk,并且在壳类型globbing方面有经验:D我会根据您的评论更正我的答案 – BonBon