2012-07-26 332 views
0

我正在提取文件中第一个和其匹配右括号之间的文本。awk脚本 - 在括号之间提取文本

输入

CREATE MULTISET TABLE ABCD.EFGH, 
NO FALLBACK, 
NO BEFORE JOURNAL, 
NO AFTER JOURNAL, 
CHECKSUM = Default 
(ABCK_SK  INTEGER   NOT NULL, 
PRQ VARCHAR(1024)   NOT NULL, 
RST DECIMAL (12,4)   NOT NULL, 
LMN  CHAR(1)   NOT NULL, 
OPQ  DATE   NOT NULL, 
PQRS  DATE   NOT NULL, 
TUV  INTEGER   NOT NULL, 
WXY  INTEGER   NOT NULL 
) UNIQUE PRIMARY INDEX ABCK_PI (ABCK_SK) 
; 

期望输出

ABCK_SK  INTEGER   NOT NULL, 
PRQ VARCHAR(1024)   NOT NULL, 
RST DECIMAL (12,4)   NOT NULL, 
LMN  CHAR(1)   NOT NULL, 
OPQ  DATE   NOT NULL, 
PQRS  DATE   NOT NULL, 
TUV  INTEGER   NOT NULL, 
WXY  INTEGER   NOT NULL 

我写了下面的脚本让行数和列数从那里到文本需要被提取,其中,但我无法真正打印输出。任何建议将不胜感激。 感谢

#!/bin/sh 
nawk 'BEGIN{startln=0;j=0;i=0;endln=0;startchr=0;endchr=0} { 
i=1; while(i<=NF) { 
if($i=="(" && startln==0){startchr=i; startln=NR} 
if($i==")"){j=j-1} 
if($i=="("){j=j+1} 
if(j==0){endchr=i;endln=NR;break} 
i=i+1}} 
END{ 
print "startln="startln " startchr="startchr " endln="endln " endchr="endchr}' $1 

回答

0

perl解决方案:

perl -e '$/=\1; 
    while(<>) { 
     if(/\)/) { $c -=1; exit unless $c } 
     print if $c > 0; 
     $c += /\(/ 
    }' input-file 
+0

这似乎是对我完美的工作..我只需要将其嵌入我的主要scrpt,并确保它不会在我给它的不同类型的输入失败..非常感谢!从昨天早上起,这让我彻底失败了.. – user973363 2012-07-26 18:37:44

0

这里是一个很好的方式提取包含在第一个匹配的括号内的数据:

sed -n -e '1,/(/s/[^(]*/foo/' -e '/(/,$p' input-file | m4 -D 'foo=$* m4exit(0)' 

战略经济对话取代所有文字之前,先开括号与文本foo,然后使用m4与名为foo的宏定义,只是输出其第一个参数,然后丢弃剩余的数据。 m4具有非常强大的括号解析,所以这应该适用于大多数情况。 (注意,如果您封闭的文本包含后跟一个(字符串foo这将失败比选择其他foo一些独特的字符串。)

+0

这似乎不适合我。
我得到的输出是
ABCK_SK INTEGER NOT NULL我必须按如下所示运行命令,因为它给我的命令在solaris上找不到。
sed -n -e'1,/(/ s/[^(] */foo /'-e'/(/,$ p'输入文件|/usr/ccs/bin/m4 -D'foo = 1/usr/ccs/bin/m4exit(1)' – user973363 2012-07-26 17:24:57

+0

另外还有一点需要注意的是我的输入不需要第一个(就像第一个提交的行,例如,这可能是** CHECKSUM = Default(ABCK_SK INTEGER NOT NULL,** – user973363 2012-07-26 17:36:50

+0

对不起,您应该在foo的定义中使用'$ *'而不是'$ 1'编辑。 – 2012-07-26 17:49:43

1

用法:
awk -f foo.awk foo.txt

foo.awk

BEGIN { 
    ORS="" 
    RS="[()]" 
} 

RT=="(" { 
    s++; 
    if (s>1) print $0 RT 
} 


RT==")" { 
    s--; 
    if (s==0) { 
     print $0 "\n" 
     exit 
    } else { 
     print $0 RT 
    } 
} 
+0

谢谢如果我的开头和结尾括号是行中的第一个字段,那么脚本对我有效括号在一行的中间。我需要它来处理这两种情况。 – user973363 2012-07-26 18:23:26

+0

我更新了脚本。 – slitvinov 2012-07-26 18:57:30