用gawk中的空格,引号或括号定义字段

时间:2016-04-23 19:56:46

标签: regex awk gawk

我有一个文本文件,格式如下:

RANDOM-WORD1 ==> "string with whitespaces" (string with whitespaces)
RANDOM-WORD2 ==> "another string" (and another)
RANDOM-WORD3 ==> "yet another string" (and another)

我想通过以下方式定义gawk分隔符:

  • 空格
  • 报价
  • 括号

例如,第1行:

$1: RANDOM-WORD1
$2: ==>
$3: "string with whitespaces"
$4: (string with whitespaces)

我已阅读gawk' FPAT manual并且我写了这封信:

FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\([^)]+\))"

但是,它不适用于括号,因为我得到了:

$1: RANDOM-WORD1
$2: ==>
$3: "string with whitespaces"
$4: (string

我试图逃避第三个条款中的括号,但它也无法工作。我想忽略一对)内不是( ... )的任何字符。我知道事实上不会有任何嵌套的括号。

注意:我怎么能忽略引号/括号作为字段数据?例如:

$1: RANDOM-WORD1
$2: ==>
$3: string with whitespaces
$4: string with whitespaces

3 个答案:

答案 0 :(得分:1)

FPAT = "([^ ]+)|([(][^)]+[)])|(\"[^\"]+\")"对我有用。它使用了[ ]()不需要引用的技巧。

关于剥离引号或括号的第二个问题,我没有比添加这样的动作更好的想法:

{ for( i=1; i<= NF; i++ ) {
    b = substr( $i, 1, 1 );
    e = substr( $i, length( $i ), 1 );
    if( ( b == "\"" || b == "(" ) && (b == e) ) {
      $i = substr( $i,2 , length( $i ) - 2 )
    }
  }
}

答案 1 :(得分:1)

至于括号,你需要将它们转义两次

FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\\([^\\)]+\\))"

要删除括号和引号,请使用substr

$3 = substr($3, 2, length($3) - 2);
$4 = substr($4, 2, length($4) - 2);

答案 2 :(得分:0)

我不会使用FPAT,因为你的字段有一个订单,而不仅仅是一个模式。我使用第3个arg来匹配(),因为它更简单,更健壮:

match($0,/(\S+)\s(\S+)\s"([^"]+)"\s\(([^)]+).*/,a)

e.g:

$ awk 'match($0,/(\S+)\s(\S+)\s"([^"]+)"\s\(([^)]+).*/,a) { print; for (i=1; i in a; i++) printf "a[%d]: %s\n", i, a[i] }' file
RANDOM-WORD1 ==> "string with whitespaces" (string with whitespaces)
a[1]: RANDOM-WORD1
a[2]: ==>
a[3]: string with whitespaces
a[4]: string with whitespaces
RANDOM-WORD2 ==> "another string" (and another)
a[1]: RANDOM-WORD2
a[2]: ==>
a[3]: another string
a[4]: and another
RANDOM-WORD3 ==> "yet another string" (and another)
a[1]: RANDOM-WORD3
a[2]: ==>
a[3]: yet another string
a[4]: and another