awk脚本 - 在括号之间提取文本

时间:2012-07-26 16:24:27

标签: 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

3 个答案:

答案 0 :(得分:0)

这是提取第一个匹配括号中包含的数据的好方法:

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

sed将第一个打开paren之前的所有文本替换为文本foo,然后使用m4定义一个名为foo的宏,只输出其第一个参数,然后丢弃剩余的数据。 m4具有相当强大的括号解析,因此这适用于大多数情况。 (请注意,如果您的随附文字包含字符串foo后跟(,则会失败。请选择foo以外的其他字符串。)

答案 1 :(得分:0)

用法:
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
    }
}

答案 2 :(得分:0)

perl解决方案:

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