【发布时间】:2011-02-06 06:18:43
【问题描述】:
给定以下命令,
echo "1: " | awk '/1/ -F ":" {print $1}'
为什么 AWK 输出:
1:
?
【问题讨论】:
给定以下命令,
echo "1: " | awk '/1/ -F ":" {print $1}'
为什么 AWK 输出:
1:
?
【问题讨论】:
“-F”是命令行参数,不是 AWK 语法。试试:
echo "1: " | awk -F ":" '/1/ {print $1}'
【讨论】:
(pattern){action}。如果pattern(主要是条件语句)为true,则执行action。如果pattern 不可用,则暗示true。这里的pattern 是/1/,它声明是正则表达式1 在当前记录$0 中匹配
如果您想以编程方式进行,可以使用FS 变量:
echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'
请注意,如果您在主循环而不是BEGIN 循环中更改它,它会影响读入的 next 行,因为当前行已经被拆分。
【讨论】:
您有多种方法可以将: 设置为分隔符:
awk -F: '{print $1}'
awk -v FS=: '{print $1}'
awk '{print $1}' FS=:
awk 'BEGIN{FS=":"} {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 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1
【讨论】:
BEGIN 语句的最后一个示例是最正确的(与整体awk 语法一致)。
BEGIN,而-F 在单行中会派上用场。
awk 'BEGIN{print split("foo:bar",a)}' FS=":" file 和 awk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
-F 是 awk 本身的参数:
$echo "1: " | awk -F":" '/1/ {print $1}'
1
【讨论】:
您还可以使用正则表达式作为字段分隔符。下面将通过使用正则表达式将数字“10”设置为分隔符来打印“bar”。
echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'
【讨论】:
没有必要写这么多。只需在 AWK 命令中使用 -F 选项输入所需的字段分隔符,并根据您提到的字段分隔符将要打印的列号分开。
echo "1: " | awk -F: '{print $1}'
1
echo "1#2" | awk -F# '{print $1}'
1
【讨论】:
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 的答案包含了很好的语法...
【讨论】:
或者你可以使用:
echo "1: " | awk '/1/{print $1-":"}'
这是一个非常有趣的方程式。
【讨论】:
/1/ 是什么意思?