如何使用“:”作为 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=":" file
和 awk 'BEGINFS=":"; print split("foo:bar",a)' file
@kvantour 好点。我刚刚在Why is field separator taken into account differently if set before or after the expression? 中询问过。
谢谢!我从清晰的例子中学习得最好。【参考方案4】:
-F
是 awk
本身的参数:
$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 字段分隔符?的主要内容,如果未能解决你的问题,请参考以下文章