我有一个包含内容的文件:
aaa.bbb.ccc ddd.eee.fff.ggg h.i.j.k
Run Code Online (Sandbox Code Playgroud)
如果我使用代码:
awk '{sub(/\.$/, ""); print $1}' test.txt
returns aaa.bbb.ccc
awk '{sub(/\.$/, ""); print $3}' test.txt
Returns: h.i.j.k
Run Code Online (Sandbox Code Playgroud)
我理解子函数被用作:sub(regexp,replacement,target)
我不明白这部分 .$/,来自子函数。.$ 是什么?
谢谢
更新
好的,我喜欢你解释事情的方式 - 谢谢!
如果我把它应用到一个真实的例子中,
/usr/bin/host 172.0.0.10
01.0.0.172.in-addr.arpa 域名指针hostname.domain.com。
/usr/bin/host 172.0.0.10 | /bin/awk '{sub(/.$/, ""); 打印 $5}' 给出:hostname.domain.com
/usr/bin/host 172.0.0.10| /bin/awk '{sub(/.$/, ""); 打印 $1}' 给出:10.0.0.172.in-addr.arpa
- 子函数将匹配到行尾,因为有一个“。” - “”在做什么?-我不明白 awk 是如何将东西分成几列的?
sub(/regexp/, replacement, target)
sub(/\.$/, replacement, target)
Run Code Online (Sandbox Code Playgroud)
你的正则表达式是\.$,不是.$/
\是转义字符。它转义了跟在它后面的字符,从而将它从regex意义中剥离出来并按字面意思处理。
.inregex匹配任何单个字符。除非它\在你的例子中被转义,因此它只匹配点字符.
$ 只是意味着行的结束。
将它们放在一起,\.$是该行末尾的转义点。例如,这将匹配以句点结尾的任何段落结尾。
在您的示例中, thesub不会替换任何内容,因为.行尾没有(您的输入以 结尾.k。所以您的第一个awk只打印第一列,另一个打印第三列。
更新
对于您更新的问题。
默认情况下,awk 按空格分割列中的字符串。因此,在您的输入中,列是这样的:
01.0.0.172.in-addr.arpa domain name pointer hostname.domain.com.
|----------$1-----------|--$2--|-$3-|--$4---|----------$5--------|
Run Code Online (Sandbox Code Playgroud)
在您的sub命令中,awk 找到行尾的点并替换""为空字符串(即它只是删除它)
所以你的第一个命令 - {sub(/.$/, ""); print $5},它打印第 5 列,hostname.domain.com.在它.用任何东西替换末尾之后(删除它)。值得注意的是,在此正则表达式中,您不再转义 the .,因此该模式仅匹配末尾的任何字符并将其删除(它恰好是.您输入中的 a)
您的其他命令 -{sub(/.$/, ""); print $1}删除行尾的字符,然后只打印第一列10.0.0.172.in-addr.arpa
您还可以在 awk 中设置自定义列分隔符,我建议您阅读一些有关 awk 的介绍和教程,以更好地了解它的工作原理。例如简单的 awk 教程
sub(regexp, replacement, target)
所以这里我们使用正则表达式 as \.$,它匹配末尾的点。这里sub(/\.$/, "")我们没有提到目标,所以它需要$0整行。如果您指定任何 target ,它将仅删除该特定列上的最后一个点。
awk '{sub(/\.$/, ""); print $1}' test.txt
Run Code Online (Sandbox Code Playgroud)
删除仅出现在行尾的点并仅打印第 1 列。如果最后没有点,则不会发生替换。
awk '{sub(/\.$/, ""); print $3}' test.txt
Run Code Online (Sandbox Code Playgroud)
删除行末尾的点并仅打印第 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
Run Code Online (Sandbox Code Playgroud)