使用 awk 使用多字符分隔符分隔字段

hun*_*ter 7 awk

我想打印由|~^. 我尝试了很多方法,但无法使用awk. 以下是文件内容供参考。

输入

H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05|~^10.00
R|~^abc|~^2019-03-05|~^20.00
R|~^abc|~^2019-03-05|~^30.00
R|~^abc|~^2019-03-06|~^100.00
R|~^abc|~^2019-03-06|~^15.00
R|~^abc|~^2019-03-06|~^10.00
T|~^20200425|~^6|~^185.00
Run Code Online (Sandbox Code Playgroud)

我需要|~^使用awk. 我试过

cat input |grep "^T"|awk -F '|~^' '{print $2}'
Run Code Online (Sandbox Code Playgroud)

但它返回空值。

有什么建议?

Adm*_*Bee 18

我认为您面临的问题与 (GNU)awk联机帮助页 [1] 中的以下语句有关:

如果 FS 是单个字符,则字段由该字符分隔。如果 FS 是空字符串,则每个单独的字符都成为一个单独的字段。否则, FS 应该是一个完整的正则表达式

由于您的字段分隔模式包含在正则表达式(the|和 the ^)中具有特殊含义的字符,因此您需要正确转义它们。由于awk解释变量的方式(字符串文字被解析两次),您需要指定使用双反斜杠,如

awk -F '\\|~\\^' '{print $2}' input.txt
Run Code Online (Sandbox Code Playgroud)

您的示例的结果输出:

20200425
abc
abc
abc
abc
abc
abc
20200425
Run Code Online (Sandbox Code Playgroud)

要仅考虑以 开头的行T,请使用

awk -F '\\|~\\^' '/^T/ {print $2}' input.txt
Run Code Online (Sandbox Code Playgroud)

或者,通过仅选择某个字段(此处为第一个字段)的值为 的行T

awk -F '\\|~\\^' '$1=="T" {print $2}' input.txt
Run Code Online (Sandbox Code Playgroud)

两种情况下您的示例的结果

20200425
Run Code Online (Sandbox Code Playgroud)

请注意,一般情况下awk,很少需要结合使用,grepsed。此外,所有这些工具都可以直接访问文件,因此cat也没有必要使用它们来提供要处理的文本。

[1]:作为(不相关的)旁注:具有“空字符串”的部分不适用于所有 Awk 变体。GNU Awk 手册声明“这是一个通用扩展;POSIX 标准没有指定它”。