在 gawk 中通过空格、引号或括号定义字段
Define fields by whitespace, quotes or parentheses in gawk
我有一个格式如下的文本文件:
RANDOM-WORD1 ==> "string with whitespaces" (string with whitespaces)
RANDOM-WORD2 ==> "another string" (and another)
RANDOM-WORD3 ==> "yet another string" (and another)
我想通过以下方式定义 gawk
个分隔符:
- 空格
- 引用
- 括号
例如,第 1 行:
: RANDOM-WORD1
: ==>
: "string with whitespaces"
: (string with whitespaces)
我读过 gawk
的 FPAT
manual 我写了这个:
FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\([^)]+\))"
但是,它对括号不起作用,因为我得到:
: RANDOM-WORD1
: ==>
: "string with whitespaces"
: (string
我试过转义第三个子句中的括号,但它也不起作用。我想忽略一对 ( ... )
中的任何不是 )
的字符。我知道不会有任何嵌套括号的事实。
注意:我怎样才能同时忽略 quotes/parentheses 作为字段数据?例如:
: RANDOM-WORD1
: ==>
: string with whitespaces
: string with whitespaces
这个 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 )
}
}
}
至于括号,需要转义两次:
FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\([^\)]+\))"
要删除括号和引号,请使用 substr
:
= substr(, 2, length() - 2);
= substr(, 2, length() - 2);
我不会为此使用 FPAT,因为您的字段有顺序,而不仅仅是模式。我会使用第三个参数来匹配(),因为它更简单、更健壮:
match([=10=],/(\S+)\s(\S+)\s"([^"]+)"\s\(([^)]+).*/,a)
例如:
$ awk 'match([=11=],/(\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
我有一个格式如下的文本文件:
RANDOM-WORD1 ==> "string with whitespaces" (string with whitespaces)
RANDOM-WORD2 ==> "another string" (and another)
RANDOM-WORD3 ==> "yet another string" (and another)
我想通过以下方式定义 gawk
个分隔符:
- 空格
- 引用
- 括号
例如,第 1 行:
: RANDOM-WORD1
: ==>
: "string with whitespaces"
: (string with whitespaces)
我读过 gawk
的 FPAT
manual 我写了这个:
FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\([^)]+\))"
但是,它对括号不起作用,因为我得到:
: RANDOM-WORD1
: ==>
: "string with whitespaces"
: (string
我试过转义第三个子句中的括号,但它也不起作用。我想忽略一对 ( ... )
中的任何不是 )
的字符。我知道不会有任何嵌套括号的事实。
注意:我怎样才能同时忽略 quotes/parentheses 作为字段数据?例如:
: RANDOM-WORD1
: ==>
: string with whitespaces
: string with whitespaces
这个 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 )
}
}
}
至于括号,需要转义两次:
FPAT = "([^[:blank:]]*)|(\"[^\"]+\")|(\([^\)]+\))"
要删除括号和引号,请使用 substr
:
= substr(, 2, length() - 2);
= substr(, 2, length() - 2);
我不会为此使用 FPAT,因为您的字段有顺序,而不仅仅是模式。我会使用第三个参数来匹配(),因为它更简单、更健壮:
match([=10=],/(\S+)\s(\S+)\s"([^"]+)"\s\(([^)]+).*/,a)
例如:
$ awk 'match([=11=],/(\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