2012-07-26 75 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

相關問題