使用 AWK,我通过将文本文件拆分为多个记录来处理该文本文件。我使用正则表达式作为记录分隔符RS。有没有办法获取RS仅代表正则表达式字符串的找到的记录分隔符?
例子:
BEGIN { RS="a[0-9]*. "; ORS="\n-----\n"}
/foo/ {print $0 RS;}
END {}
Run Code Online (Sandbox Code Playgroud)
输入文件:
a1. Hello
this
is foo
a2. hello
this
is bar
a3. Hello
this
is foo
Run Code Online (Sandbox Code Playgroud)
输出:
Hello
this
is foo
a[0-9]*.
-----
Hello
this
is foo
a[0-9]*.
-----
Run Code Online (Sandbox Code Playgroud)
如您所见,输出打印RS为表示正则表达式的字符串,但不打印实际值。如何检索记录分隔符的实际匹配值?
预期输出:
Hello
this
is foo
a1
-----
Hello
this
is foo
a3
-----
Run Code Online (Sandbox Code Playgroud)
在符合 POSIX 标准的 AWK 中,记录分隔符RS只是一个字符,因此很容易以 的形式调用它。
awk \'BEGIN{RS="a"}{print $0 RS}\'\nRun Code Online (Sandbox Code Playgroud)\n另一方面,GNU AWK 不限RS于单字符字符串,而是允许它是任何正则表达式。在这种情况下,使用上面的 AWK 会变得有点棘手,因为RS是正则表达式而不是字符串。
为此,GNU AWK 引入了变量RT,该变量仅代表找到的记录分隔符。当RS是单个字符时,RT包含相同的单个字符。但是,whenRS是正则表达式,RT包含与正则表达式匹配的实际输入文本。
如此天真地,人们可以将您的 AWK 程序更新为:
\nBEGIN{RS="a[0-9]+[.] "; ORS="\\n-----\\n"}\n/foo/{print $0 RT}\nRun Code Online (Sandbox Code Playgroud)\n不幸的是,RT被设置为当前记录之后找到的值,并且OP似乎请求当前记录之前的值,因此您可以引入一个新变量,pRT该变量可以被读取为发现的先前记录分隔符。
BEGIN{RS="a[0-9]+[.] "; ORS="\\n-----\\n"}\n/foo/{print $0 pRT}{pRT=RT}\nRun Code Online (Sandbox Code Playgroud)\n正如Shaki Siegal在评论中指出的那样,您仍然需要更新pRT以删除最后的空格和点:
BEGIN{RS="a[0-9]+[.] "; ORS="\\n-----\\n"}\n/foo/{print $0 pRT}{pRT=RT;sub(/[.] $/,"",pRT)}\nRun Code Online (Sandbox Code Playgroud)\n注意:RS OP ( ) 的原始版本RS="a[0-9]*. "已更新,以改进与 的匹配。RS="a[0-9]+[.] "这确保了后面的数字a和实际的的出现.。
如果,如原始示例所示,记录分隔符始终出现在行的开头,RS则应稍微修改为RS="(^|\\n)a[0-9]+[.] "Dito 注释也提出了各种精彩的观点。因此,如果字符串a[0-9]+. 总是出现在开头,则需要进行更多处理:
BEGIN {\n RS ="(^|\\n)a[0-9]+[.] ";\n ORS="\\n-----\\n"\n}\n/foo/ {\n if (RT ~ /^$/ && NR != 2) pRT = substr(pRT,2)\n print $0 pRT \n}\n{pRT=RT;sub(/[.] $/,"",pRT)}\nRun Code Online (Sandbox Code Playgroud)\n在这里,我们添加了一个更正来修复最后一条记录。
\npRT,否则您将包含由最后一条以换行符结尾的记录引起的额外换行符 (与所有其他人相反)。RT不以换行符开头最后的改进是通过意识到我们总是删除初始换行符(pRT如果存在)来完成的,因此我们可以将其全部合并到一个中gsub:
BEGIN {\n RS ="(^|\\n)a[0-9]+[.] ";\n ORS="\\n-----\\n"\n}\n/foo/ { print $0 pRT }\n{pRT=RT;gsub(/^\\n|[.] $/,"",pRT)}\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n
RS:输入记录分隔符。它的默认值是包含单个换行符的字符串,这意味着输入记录由单行文本组成。它也可以是空字符串,在这种情况下,记录由空行分隔。如果它是正则表达式,则记录由输入文本中正则表达式的匹配项分隔。\n
RS成为正则表达式的能力是一种gawk扩展。在大多数其他 AWK 实现中,或者如果gawk处于兼容模式(请参阅选项),则仅RS使用 \xe2\x80\x99s 值的第一个字符。\n
ORS:输出记录分隔符。它在每个打印语句的末尾输出。它的默认值为“\\n”,即换行符。\n
RT:RS(GNU AWK 特定)与记录分隔符表示的文本匹配的输入文本。每次读取记录时都会设置它。来源:GNU AWK 手册
\n
| 归档时间: |
|
| 查看次数: |
1051 次 |
| 最近记录: |