[英]RS in awk language
我正在学习awk编程语言,并且在这里遇到了问题。
我有一个文件(awk.dat),具有以下内容:
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.
我正在使用以下命令:
awk 'BEGIN{RS="*, *";ORS="<<<---\n"} {print $0}' awk.dat
返回错误:
awk: run time error: regular expression compile failed (missing operand)
*, *
FILENAME="" FNR=0 NR=0
同时,如果我使用以下命令: awk 'BEGIN{RS=" *, *";ORS="<<<---\\n"} {print $0}' awk.dat
,它给了我所需的结果。
我需要了解这一部分: RS=" *, *"
,双引号之间的空间的意义*
之前,
由于它的投掷的错误。
预期产量:
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci<<<---
euismod id nisi eget<<<---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat<<<---
et facilisis.
<<<---
谢谢。
"[space1]*,[space2]*"
是一个正则表达式,它与以下字符串匹配:
零个或多个空格(space1),后跟一个逗号,然后是零个或多个空格(space2)
第一个"*,[space]*"
是错误的,因为*
在正则表达式中具有特殊含义。 这意味着将匹配的组/字符重复零次或多次。 您不能一开始就将其放置。
请注意,根据POSIX, RS
被定义为单个字符而不是正则表达式。
RS
字符串值的第一个字符应为输入记录分隔符; 默认情况下为<newline>。 如果RS
包含多个字符,则结果不确定。 如果RS
为空,则记录由由<newline>加上一个或多个空行组成的序列分隔,开头或结尾的空行在输入的开头或结尾不应导致空记录,而<newline>应不管FS
的值是多少,始终是字段分隔符。来源: Awk Posix标准
这意味着RS=" *, *"
导致未定义的行为 。
实现POSIX扩展的其他版本的awk,对于RS
含义可能有不同的方法。 例如GNU awk和mawk。 两者都将RS
实现为正则表达式,但是两种实现都略有不同。 <asterisk>用法的摘要如下:
| RS | awk (posix) | gawk | mawk |
|------+--------------+------------------+------------------|
| "*" | "<asterisk>" | "<asterisk>" | "<asterisk>" |
| "*c" | undefined | "<asterisk>c" | undefined |
| "c*" | undefined | "","c","ccc",... | "","c","ccc",... |
c is any character
上面应该解释OP的错误,因为根据mawk RS="*, *"
是无效的正则表达式。
$ echo "abc" | ./mawk '/*c/'
mawk: line 1: regular expression compile failed (missing operand)
GNU awk:GNU awk的手册规定如下:
使用
gawk
,RS
的值不限于一个字符的字符串。 它可以是任何正则表达式 (请参阅Regexp )。 (ce)通常,每条记录在与正则表达式匹配的下一个字符串处结束; 下一条记录从匹配字符串的末尾开始。来源: GNU awk手册
为了了解<asterisk>在GNU awk中的正则表达式中的用法,我们发现:
<星号>
*
此符号表示前面的正则表达式应重复多次以找到匹配项。 例如,ph*
将*
符号应用于前面的h
并查找一个p
匹配项,后跟任意数量的h
s。 如果不存在h
则也仅匹配p
。要了解
*
工作原理,有两点要*
。 首先,*
仅适用于单个前面的正则表达式分量(例如,在ph*
,它仅适用于h
)。 要使*
应用于较大的子表达式,请使用括号:(ph)*
匹配ph
,phph
,phphph
等。其次,
*
查找尽可能多的重复。 如果要匹配的文本是phhhhhhhhhhhhhhooey
,则ph*
匹配所有h
s。来源: GNU正则表达式运算符
但必须指出的是:
在
POSIX awk和gawk中,*
,+
和?
当正则表达式中没有任何运算符时,运算符将代表自己。 例如,/+/
匹配文字加号。 但是,awk的许多其他版本将这种用法视为语法错误。来源: GNU正则表达式运算符
因此,设置RS="*, *"
意味着它将与字符串"*,"
, "*, "
, "*, "
,...相匹配。
$ echo "a,b, c" | awk 'BEGIN{RS="*, *"}1'
a,b, c
$ echo "a*,b, c" | awk 'BEGIN{RS="*, *"}1'
a
b, c
mawk: GNU awk的手册规定如下:
12.多行记录
由于mawk
将RS
解释为正则表达式 ,因此多行记录很容易。资料来源:
man mawk
但
11.分割字符串,记录和文件
Awk程序使用相同的算法通过split()
将字符串拆分为数组,并记录到FS
字段中。 mawk使用基本上相同的算法将文件拆分为RS
记录。
Split(expr,A,sep)
工作方式如下:
- <snip>
- 如果
sep = " "
(单个空格),则从expr
的前后修剪<SPACE>,并且sep
变为<SPACE>。 mawk将<SPACE>定义为正则表达式/[ \\t\\n]+/
。 否则,sep
会被视为正则表达式, 只是对于长度为1的字符串会忽略元字符 ,例如split(x, A, "*")
和split(x, A, /\\*/)
相同。- <snip>
资料来源:
man mawk
该手册未提及应如何解释以元字符开头的正则表达式(例如“ * c”)
注意:在GNU awk部分中,我介绍了POSIX awk,因为根据POSIX,形式为"*, "
的正则表达式会导致未定义的行为。 (这与定义RS
无关,因为RS
在POSIX awk中始终不是ERE)
awk实用程序应使用扩展的正则表达式符号(请参阅XBD 扩展的正则表达式 )
来源: Awk Posix标准
和
*+?{
除在方括号表达式中使用时,<asterisk>,<加号>,<question-mark>和<left-brace>应该是特殊的(请参阅RE方括号表达式)。 以下任何一种用途都会产生不确定的结果:
- 如果这些字符首先出现在ERE中 ,或者紧随未转义的<vertical-line>,<circumflex>,<dollar-sign>或<left-parenthesis>之后出现
- 如果<left-brace>不是有效间隔表达式的一部分(请参阅匹配多个字符的ERE)
来源: POSIX扩展正则表达式
您能否再尝试一次。
awk '{gsub(", ","<<<---" ORS)} 1;END{print "<<<---"}' Input_file
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.