Bash 适用于awk v4.0.2但不适用于>;=4.2.1
我有这个awk命令:Bash 适用于awk v4.0.2但不适用于>;=4.2.1,bash,ubuntu,awk,centos7,alpine,Bash,Ubuntu,Awk,Centos7,Alpine,我有这个awk命令: echo www.host.com |awk -F. '{$1="";OFS="." ; print $0}' | sed 's/^.//' 它所做的是从主机名获取域: host.com 该命令适用于CentOS 7(awk v 4.0.2),但不适用于ubuntu 19.04(awk 4.2.1)或alpine(gawk 5.0.1),输出为: host com 如何修复该awk表达式,使其在最新的awk版本中工作?对于您提供的示例,请尝试以下内容。这将尝试从第一个
echo www.host.com |awk -F. '{$1="";OFS="." ; print $0}' | sed 's/^.//'
它所做的是从主机名获取域:
host.com
该命令适用于CentOS 7(awk v 4.0.2),但不适用于ubuntu 19.04(awk 4.2.1)或alpine(gawk 5.0.1),输出为:
host com
如何修复该awk表达式,使其在最新的awk版本中工作?对于您提供的示例,请尝试以下内容。这将尝试从第一个
到最后一行匹配正则表达式,然后从第一个点到最后一行打印
echo www.host.com | awk 'match($0,/\..*/){print substr($0,RSTART+1,RLENGTH-1)}'
OP的代码修复:如果OP想要使用他/她自己尝试过的代码,那么下面可能会有所帮助。这里有两点:1-我们不需要使用任何其他命令以及
awk
来进行处理。第二-我们需要在每个行中执行的BEGIN
部分中设置FS
和OFS
的值
echo www.host.com | awk 'BEGIN{FS=OFS="."} {$1="";sub(/\./,"");print}'
对于您提供的样品,请尝试以下内容。这将尝试从第一个
到最后一行匹配正则表达式,然后从第一个点到最后一行打印
echo www.host.com | awk 'match($0,/\..*/){print substr($0,RSTART+1,RLENGTH-1)}'
OP的代码修复:如果OP想要使用他/她自己尝试过的代码,那么下面可能会有所帮助。这里有两点:1-我们不需要使用任何其他命令以及
awk
来进行处理。第二-我们需要在每个行中执行的BEGIN
部分中设置FS
和OFS
的值
echo www.host.com | awk 'BEGIN{FS=OFS="."} {$1="";sub(/\./,"");print}'
要获取域,请使用:
$ echo www.host.com | awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'
host.com
解释:
awk '
BEGIN { # before processing the data
FS=OFS="." # set input and output delimiters to .
}
{
print $(NF-1),$NF # then print the next-to-last and last fields
}'
如果您有任意长的FQDN,它也可以工作:
$ echo if.you.have.arbitrarily.long.fqdns.example.com |
awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'
example.com
是的,有趣的是,你的版本真的适用于4.0.2。和awk版本20121220
更新:
更新了一些内容检查功能,请参见备注。是否有超过三个级别的域
$ echo and.with.peculiar.fqdns.like.co.uk |
awk '
BEGIN {
FS=OFS="."
pecs["co\034uk"]
}
{
print (($(NF-1),$NF) in pecs?$(NF-2) OFS:"")$(NF-1),$NF
}'
like.co.uk
要获取域,请使用:
$ echo www.host.com | awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'
host.com
解释:
awk '
BEGIN { # before processing the data
FS=OFS="." # set input and output delimiters to .
}
{
print $(NF-1),$NF # then print the next-to-last and last fields
}'
如果您有任意长的FQDN,它也可以工作:
$ echo if.you.have.arbitrarily.long.fqdns.example.com |
awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'
example.com
是的,有趣的是,你的版本真的适用于4.0.2。和awk版本20121220
更新:
更新了一些内容检查功能,请参见备注。是否有超过三个级别的域
$ echo and.with.peculiar.fqdns.like.co.uk |
awk '
BEGIN {
FS=OFS="."
pecs["co\034uk"]
}
{
print (($(NF-1),$NF) in pecs?$(NF-2) OFS:"")$(NF-1),$NF
}'
like.co.uk
你在awk上得到了2个非常好的答案,但我认为这应该通过
cut
来处理,因为它提供了从已知位置开始的所有字段的简单性:
echo 'www.host.com' | cut -d. -f2-
使用的选项包括:
:将分隔符设置为-d.
:从位置2开始提取所有字段-f2-
cut
来处理,因为它提供了从已知位置开始的所有字段的简单性:
echo 'www.host.com' | cut -d. -f2-
使用的选项包括:
:将分隔符设置为-d.
:从位置2开始提取所有字段-f2-
$0
,则正在设置的OFS应使用以前的OFS
重新生成$0
重建。感谢迈克·布伦南指出这一点
- awk.h(
):声明李>重建记录
- eval.c(
):如果没有从set\u of s
调用,请检查var\u init()
是否需要重建。如果是这样,请完全解析记录并重建它。使$0
下次指向新的OFS
的单独副本,因为OFS
是 现在已经更新了OFS\u节点->var\u值->stptr
- field.c(
):现在是外部的,而不是静态的。使用OFS的rebuild\u record
和OFSlen的OFS
而不是OFS\u节点的OFS
值
awk -F. '{$1="";OFS="." ; print $0}'
根据POSIX的规定,其功能如下:
-F.
:设置字段分隔符FS
以表示-字符FS=“.”
$1=”“
:使用OFS重新定义字段1并重建记录$0
。此时,OFS
被设置为单个空间。如果记录$0
是www.foo.com
,则它现在将读取\u foo\u com
(下划线表示空格)。重新计算现在只有一个的字段数,因为不再有可用的FS
OFS=“.”
:将输出字段分隔符OFS
重新定义为-字符。这就是bug发生的地方。Gnu awk知道需要进行重建,但已经用新的OFS而不是旧的OFS进行了重建打印$0':**打印记录$0,该记录现在是
\u foo\u com`awk -F. '{OFS="."; $1=""; print $0}'
awk 'BEGIN{FS=OFS="."}{$1="";print $0}'
彻底的改变是:
awk -F. '{OFS="."; $1=""; print $0}'
awk 'BEGIN{FS=OFS="."}{$1="";print $0}'
最完美的改变是将awk
和sed
替换为
如果其中有一个具有该名称的变量,则可以使用:
var=www.foo.com
echo ${var#*.}
您所看到的是GNU awk中的一个bug,它在4.2.1版中得到了修复。changlog说: 2014-08-12阿诺德·罗宾斯 如果需要重新设置
$0
,则正在设置的OFS应使用以前的OFS
重新生成$0
重建。感谢迈克·布伦南指出这一点
- awk.h(
):声明李>重建记录
- eval.c(
):如果没有从set\u of s
调用,请检查var\u init()
是否需要重建。如果是这样,请完全解析记录并重建它。使$0
下次指向新的OFS
的单独副本,因为OFS
是 现在已经更新了OFS\u节点->var\u值->stptr