替换除最后 x 次之外的字符

Flo*_*rin 11 sed text-processing regular-expression

我有一个文件,其中包含一堆与 IP 相关的主机名,如下所示:

x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int.test.example.com 59.2.86.3
super.awesome.machine 123.234.15.6
Run Code Online (Sandbox Code Playgroud)

我希望它看起来像这样:

x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int-test-example-com 59.2.86.3
super-awesome-machine 123.234.15.6
Run Code Online (Sandbox Code Playgroud)

我该如何更换 . (点)从第一列带 - (连字符)以便于按第二列排序?我正在考虑使用 sed 替换点直到第一个空格,或者替换除最后三个之外的每个点,但我无法理解正则表达式和 sed。我可以执行简单的替换,但这超出了我的能力范围!

这是我用 bash 编写的一个更大脚本的一部分。我被困在这部分。

Rah*_*til 8

您可以使用 AWK

awk '{gsub(/-/,".",$1);print}' infile
Run Code Online (Sandbox Code Playgroud)

解释

awk默认情况下在空白处拆分一行。因此,该行的第一列 ( $1in awk-ese) 将是您要对其执行替换的列。为此,您可以使用:

 gsub(regex,replacement,string)
Run Code Online (Sandbox Code Playgroud)

执行所需的替换。

请注意,gsub仅支持gawk并且nawk在许多现代发行版上awk是到gawk.

  • `awk` 的 POSIX 规范基于 `nawk`,所以所有现代的 `awk` 实现都应该有 `gsub`。在 Solaris 上,您可能需要 `/usr/xpg4/bin/awk` 或 `nawk`。 (2认同)

Sté*_*las 6

如果您需要在第一个字段上进行替换,最好使用Rahul 的 awk 解决方案,但要注意它可能会影响间距(字段用它们之间的单个空格重写)。

您可以通过编写它来避免它:

perl -pe 's|\S+|$&=~tr/./-/r|e' file
Run Code Online (Sandbox Code Playgroud)

-p标志的意思是“逐行读取输入文件并在应用”给出的脚本后打印每一行-e。然后,用匹配的模式 ( )替换 ( s|pattern|replacement|) 第一个非空格字符 ( \S+)序列,然后用. 诀窍就是使用其中运营商将计算表达式作为替换。因此,您可以将一个替换 ( ) 应用于前一个 ( )的匹配( )。$&.-s|||eetr/./-/$&s|||e

如果您需要使用 GNU替换每个.-但最后三个除外,sed并假设您有一个rev命令:

rev file | sed 's/\./-/4g' | rev
Run Code Online (Sandbox Code Playgroud)