繁体   English   中英

RS以AWK语言

[英]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的手册规定如下:

使用gawkRS的值不限于一个字符的字符串。 它可以是任何正则表达式 (请参阅Regexp )。 (ce)通常,每条记录在与正则表达式匹配的下一个字符串处结束; 下一条记录从匹配字符串的末尾开始。

来源: GNU awk手册

为了了解<asterisk>在GNU awk中的正则表达式中的用法,我们发现:

<星号> *此符号表示前面的正则表达式应重复多次以找到匹配项。 例如, ph**符号应用于前面的h并查找一个p匹配项,后跟任意数量的h s。 如果不存在h则也仅匹配p

要了解*工作原理,有两点要* 首先, *仅适用于单个前面的正则表达式分量(例如,在ph* ,它仅适用于h )。 要使*应用于较大的子表达式,请使用括号: (ph)*匹配phphphphphph等。

其次, *查找尽可能多的重复。 如果要匹配的文本是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.多行记录
由于mawkRS解释为正则表达式 ,因此多行记录很容易。

资料来源: man mawk

11.分割字符串,记录和文件
Awk程序使用相同的算法通过split()将字符串拆分为数组,并记录到FS字段中。 mawk使用基本上相同的算法将文件拆分为RS记录。

Split(expr,A,sep)工作方式如下:

  1. <snip>
  2. 如果sep = " " (单个空格),则从expr的前后修剪<SPACE>,并且sep变为<SPACE>。 mawk将<SPACE>定义为正则表达式/[ \\t\\n]+/ 否则, sep会被视为正则表达式, 只是对于长度为1的字符串会忽略元字符 ,例如split(x, A, "*")split(x, A, /\\*/)相同。
  3. <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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM