如何使用“:”作为 AWK 字段分隔符?

Posted

技术标签:

【中文标题】如何使用“:”作为 AWK 字段分隔符?【英文标题】:How can I use ":" as an AWK field separator? 【发布时间】:2011-02-06 06:18:43 【问题描述】:

给定以下命令,

echo "1: " | awk '/1/ -F ":" print $1'

为什么 AWK 输出:

1:

?

【问题讨论】:

【参考方案1】:

“-F”是命令行参数,不是 AWK 语法。试试:

 echo "1: " | awk -F  ":" '/1/ print $1'

【讨论】:

这里无知的问题:/1/ 部分是告诉 awk 只处理包含数字 1 的行(或更准确地说是记录)对吗? @rantsh awk 语法类似于(pattern)action。如果pattern(主要是条件语句)为true,则执行action。如果pattern 不可用,则暗示true。这里的pattern/1/,它声明是正则表达式1 在当前记录$0 中匹配 附带说明,如果分隔符是逗号,则需要在 awk 中添加 -v OFS="," 参数,以将其保留在输出中 如何在 .awk 脚本中指出这一点? @JoanSerrano 看看下面丹尼斯的回答就是这样做的【参考方案2】:

如果您想以编程方式进行,可以使用FS 变量:

echo "1: " | awk 'BEGIN  FS=":"  /1/  print $1 '

请注意,如果您在主循环而不是BEGIN 循环中更改它,它会影响读入的 next 行,因为当前行已经被拆分。

【讨论】:

【参考方案3】:

您有多种方法可以将: 设置为分隔符:

awk -F: 'print $1'

awk -v FS=: 'print $1'

awk 'print $1' FS=:

awk 'BEGINFS=":" print $1'

所有这些都是等效的,并且在给定示例输入“1:2:3”的情况下将返回1

$ awk -F: 'print $1' <<< "1:2:3"
1
$ awk -v FS=: 'print $1' <<< "1:2:3"
1
$ awk 'print $1' FS=: <<< "1:2:3"
1
$ awk 'BEGINFS=":" print $1' <<< "1:2:3"
1

【讨论】:

哪个是首选方式?我假设BEGIN 语句的最后一个示例是最正确的(与整体awk 语法一致)。 @randomware 他们都很好。如果我使用文件来存储整个内容,我倾向于使用BEGIN,而-F 在单行中会派上用场。 必须说第三种情况和其他所有情况都有细微的差别。示例:awk 'BEGINprint split("foo:bar",a)' FS=":" fileawk 'BEGINFS=":"; print split("foo:bar",a)' file @kvantour 好点。我刚刚在Why is field separator taken into account differently if set before or after the expression? 中询问过。 谢谢!我从清晰的例子中学习得最好。【参考方案4】:

-Fawk 本身的参数:

$echo "1: " | awk -F":" '/1/ print $1'
1

【讨论】:

不用加冒号。【参考方案5】:

您还可以使用正则表达式作为字段分隔符。下面将通过使用正则表达式将数字“10”设置为分隔符来打印“bar”。

echo "foo 10 bar" | awk -F'[0-9][0-9]' 'print $2'

【讨论】:

【参考方案6】:

没有必要写这么多。只需在 AWK 命令中使用 -F 选项输入所需的字段分隔符,并根据您提到的字段分隔符将要打印的列号分开。

echo "1: " | awk -F: 'print $1'
1

echo "1#2" | awk -F# 'print $1'
1

【讨论】:

【参考方案7】:

AWK 用作文本解释器对整个文档逐行处理对每一行逐行处理。因此 $1, $2...$n 是对每一行字段的引用($1 是第一个字段,$2 是第二个字段,依此类推...)。

您可以使用命令行下的“-F”开关或在带有“FS=...”的两个括号内定义字段分隔符。

现在考虑the answer of Jürgen:

echo "1: " | awk -F  ":" '/1/ print $1'

在字段上方,边界由“:”设置,因此我们有两个字段 $1 是“1”,而 $2 空白区域。之后是正则表达式“/1/”,它指示过滤器仅在解释器偶然发现包含此类表达式的行(我的意思是 1)时才输出第一个字段。

“echo”命令的输出是包含“1”的一行,因此过滤器将起作用...

在处理下面的例子时:

echo "1: " | awk '/1/ -F ":" print $1'

语法混乱,解释器选择忽略F部分“:” 并切换到默认的字段拆分器,即空白区域,因此输出“1:”作为第一个字段,不会有第二个字段!

Jürgen 的答案包含了很好的语法...

【讨论】:

【参考方案8】:

或者你可以使用:

echo "1: " | awk  '/1/print $1-":"' 

这是一个非常有趣的方程式。

【讨论】:

/1/ 是什么意思? 找到一个模式。在这种情况下为“1” 为什么这是一个非常有趣的方程式? 我认为这个技巧只适用于“:”之前的值是数字。回声“ab1:”| awk '/1/print $1-":"' 失败,打印一个 "0"

以上是关于如何使用“:”作为 AWK 字段分隔符?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWK 中一次删除多个列和字段分隔符?

如何使用 sed/awk 替换逗号分隔字符串中的第 n 列/字段?

linux awk 内置变量使用介绍

二.AWK内置变量

如何在Linux中使用awk命令

三剑客之awk