regex AWK子函数语法

avwztpqn  于 2023-04-22  发布在  其他
关注(0)|答案(3)|浏览(135)

我有一个文件的内容:

aaa.bbb.ccc ddd.eee.fff.ggg h.i.j.k

如果我使用代码:

  • awk '{sub(/\.$/, ""); print $1}' test.txt

返回:aaa.bbb.ccc

  • awk '{sub(/\.$/, ""); print $3}' test.txt

返回:h.i.j.k
我知道子函数的作用是sub(regexp, replacement, target)。我不知道子函数的作用是\.$/。什么是.$
如果我把这个应用到一真实的例子中,
/usr/bin/host172.0.0.10
01.0.0.172.in-addr.arpa 域名指针hostname.domain.com。

  1. /usr/bin/host 172.0.0.10 | /bin/awk '{sub(/\.$/, ""); print $5}'
    给出:hostname.domain.com
  2. /usr/bin/host 172.0.0.10| /bin/awk '{sub(/\.$/, ""); print $1}'
    给出:10.0.0.172.in-addr.arpa
  • sub函数将匹配到行的末尾,因为存在.
  • ""是什么?
  • awk是如何把东西分成列的?
rwqw0loc

rwqw0loc1#

sub(/regexp/, replacement, target)
sub(/\.$/, replacement, target)

您的正则表达式是\.$,而不是.$/
\是转义字符。它转义后面的字符,从而将其从regex的含义中剥离出来并按字面意思处理。
regex中的.匹配任何单个字符。除非像您的示例中那样由\转义,否则它只匹配点字符.
$表示行的结束。
把这些放在一起,\.$是行尾的转义点。这将匹配例如以句点结尾的任何段落结尾。
在您的示例中,sub不会替换任何内容,因为行尾没有.(您的输入以.k结束。因此,第一个awk仅打印第1列,另一个打印第3列。

更新

你的更新问题。
Awk默认情况下通过空格将字符串拆分为列。因此在输入中,列如下所示:

01.0.0.172.in-addr.arpa domain name pointer hostname.domain.com.
|----------$1-----------|--$2--|-$3-|--$4---|----------$5--------|

在你的sub命令中,awk会找到行尾的点,并替换为空字符串""(即它只是删除它)
所以你的第一个命令-{sub(/.$/, ""); print $5},它打印了第五列,也就是hostname.domain.com.,在它将末尾的.替换为空之后值得注意的是,在这个正则表达式中,你不再转义.,所以模式只匹配结尾的 any 字符并删除它(它恰好是输入中的.
您的另一个命令-{sub(/.$/, ""); print $1}删除行最末尾的字符,然后只打印第一列10.0.0.172.in-addr.arpa
你也可以在awk中设置自定义的列分隔符,我建议你阅读一些awk的介绍和教程,以更好地了解它是如何工作的。例如simple awk tutorial

3wabscal

3wabscal2#

sub(regexp, replacement, target)
所以这里我们使用正则表达式\.$,它匹配末尾的点。这里sub(/\.$/, "")我们没有提到目标,所以它需要$0即整行。如果你指定任何目标,它只会删除特定列上的最后一个点。

awk '{sub(/\.$/, ""); print $1}' test.txt

删除仅出现在行尾的点,并仅打印列1。如果最后没有点,则不会发生替换。

awk '{sub(/\.$/, ""); print $3}' test.txt

删除行尾的点,只打印第3列。因为行尾没有点,所以它返回第三列,也就是最后一列。

示例:

$ cat file
aaa.bbb.ccc. ddd.eee.fff.ggg h.i.j.k.
$ awk '{sub(/\.$/, ""); print $1}' file
aaa.bbb.ccc.
$ awk '{sub(/\.$/, ""); print $3}' file
h.i.j.k
svujldwt

svujldwt3#

我有一个这样的表格

<table width="700" border="1" align="center" cellpadding="0" cellspacing="0" bordercolor="ffcc00" bgcolor="ffcc00">
<tbody>
        <th colspan="7" bordercolor="ffcc00" bgcolor="000000" scope="col">
            <div align="center" class="style2">
                Exciter Power Supply</div>
        </th>
    </tr>
    <tr>
        <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
            <div align="center" class="style1">+ 3 V </div>
        </th>
        <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
            <div align="center" class="style1">
                OK</div>
        </th>
        <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
            <div align="center" class="style1">&nbsp;+ 5 V</div>
        </th>
        <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
            <div align="center" class="style1">
                OK</div>
        </th>
    </tr>
    
</tbody>

当我得到**+3 V**的值时

curl -s http://my-site/index.htm | sed -e 's/<[^>]*>//g' | awk '/+ 3 V/{getline;  print}'

我有输出OK '& nbsp';+ 5 V
对于删除空格和另一个字段的文本,我使用sub()来改变字符,加上tr来删除字符

curl -s http://my-site/index.htm | sed -e 's/<[^>]*>//g' | awk '/+ 3 V/{getline; sub(/+ 5 V/, ""); print}' | tr "&nbsp;" " "

我的输出只有OK

相关问题