【问题标题】:Formatting IP with sed使用 sed 格式化 IP
【发布时间】:2016-05-14 05:13:30
【问题描述】:

我正在尝试弄清楚如何使用 sed 执行以下操作:

我得到了一个 IPv4 地址列表,我正试图让它们在显示中都统一。例如:1.2.4.32 将是 001.002.004.03210.125.62.1 将是 010.125.062.001

我正在尝试使用 sed 来做到这一点,因为这就是我现在正在学习的内容。

我得到了这两个,它将采用任何一位或两位数字并在前面附加零。

sed 's/\<[0-9][0-9]\>/0&/g' file
sed 's/\<[0-9]\>/00&/g' file

但这遇到了一个更实际的问题,因为我的输入文件将在其他非 IP 地址位置有一位或两位数字。示例:

host-1 1.2.3.32

所以我需要一种方法来寻找完整的 IP 地址,我认为可以通过这个来实现

sed 's/\.\<[0-9]\>/00&/g'

但这不仅忽略了1.something.something.something 的大小写,而且出于某种原因,它还在第三个八位字节的末尾附加了00

echo "10.10.88.5" | sed 's/\.\<[0-9]\>/00&/g'
10.10.8800.5

示例文件:

Jumpstart Server jumo     10.20.5.126
Jumpstart Server acob     10.20.5.168
NW1 H17  Node cluster     10.10.161.87
NW1 H17  Node-1       10.10.161.8
NW1 H17  Node-2       10.10.161.9
ts-nw1      10.10.8.6

【问题讨论】:

  • 文件的内容有模式吗?发布文件的摘录
  • 按要求。文件
  • 谢谢,这让问题更清楚了:)
  • 我已经有一些 sed 命令可以稍微清理文件,例如所有非 IP 条目将被连接成一个字符串,下划线连接它们,去掉多余的制表符,空白处为空行等等我从不同的人那里得到这些文件,他们都以自己特殊的方式做事。

标签: bash sed ip


【解决方案1】:

只改变行的一部分的惯用方法是将它复制到保持空间,从模式空间中删除我们不感兴趣的部分,取回保持空间,然后重新排列模式空间以替换部分我们已经用我们的新版本进行了更改。

这应该可以工作(对于 BSD sed,将 -r 替换为 -E):

sed -r 'h                  # Copy pattern space to hold space

# Remove everything except IP address from pattern space
s/.*\b(([0-9]{1,3}\.){3}[0-9]{1,3})\b.*/\1/

s/([0-9])+/00&/g           # Prepend '00' to each group of digits
s/[0-9]*([0-9]{3})/\1/g    # Only retain last three digits of each group
G                          # Append hold space to pattern space

# Replace old IP with new IP
s/(.*)\n(.*)\b([0-9]{1,3}\.){3}[0-9]{1,3}\b(.*)/\2\1\4/' infile

最后一步是最复杂的一步。就在它之前,一行看起来像这样(换行为\n,行尾为$):

010.020.005.126\nJumpstart Server jumo     10.20.5.126$

即,我们新的和改进的 IP 地址,换行符,然后是完整的旧行。我们现在捕获带下划线的组:

010.020.005.126\nJumpstart Server jumo     10.20.5.126$
^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^           ^
      (.*)     \n          (.*)              \b...\b  (.*)
       \1                   \2                  \3     \4

然后使用组 2 重新排列线路,然后使用组 1(我们的新 IP)和 4。请注意

  • 有四个捕获组,但第三个只是用来帮助描述 IP 地址,我们实际上并不想保留它,因此替换为 \2\1\4(在 sed 中没有非捕获组)。
  • 最后一个捕获组(在 IP 地址之后)是空的,但是有了它就可以将它用于在任何地方都有 IP 地址的行。
  • 这只会替换每行的第一个 IP 地址,以防有多个。

整体输出为

Jumpstart Server jumo     010.020.005.126
Jumpstart Server acob     010.020.005.168
NW1 H17  Node cluster     010.010.161.087
NW1 H17  Node-1       010.010.161.008
NW1 H17  Node-2       010.010.161.009
ts-nw1      010.010.008.006

与完全不可读的单行一样:

sed -r 'h;s/.*\b(([0-9]{1,3}\.){3}[0-9]{1,3})\b.*/\1/;s/([0-9])+/00&/g;s/[0-9]*([0-9]{3})/\1/g;G;s/(.*)\n(.*)\b([0-9]{1,3}\.){3}[0-9]{1,3}\b(.*)/\2\1\4/' infile

\b 是一个 GNU 扩展。该脚本在没有它的情况下也可以正常工作。使用它可以确保 blah1.2.3.4blah 不受影响。

【讨论】:

  • @cyrus 哎呀...上它!
  • @cyrus 那里。 s/[0-9]([0-9]{3})/\1/g 必须是 s/[0-9]*([0-9]{3})/\1/g。我的内部 QA 就这么多! ;)
  • -E 确实可以在 GNU sed 上工作,只是没有记录。
  • Nice+1,但如果 ip 不在末尾或者一行中有两个 ip,这将失败
  • @sjsam 是的,它依赖于此。 任何地方的 IP 地址都很难可靠地实现。
【解决方案2】:
$ cat 37222835.txt
Jumpstart Server jumo     10.20.5.126 10.29.23.24
Jumpstart Server acob     10.20.5.168 dig opt
Jumpstart Server reac     251.218.212.1 rel
NW1 H17  Node cluster     10.10.161.87
NW1 H17  Node-1       10.10.161.8
NW1 H17  Node-2       10.10.161.9
ts-nw1      10.10.8.6
Nw2 HW12 Node-3       192.168.0.1
cluster

在做:

sed -n 's/\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5]\)\{1\}\.'\
'\([1]\?[0-9][0-9]\?\|2[0-4][0-9]\|25[0-5] \)/00\1\.00\2\.00\3\.00\4/g;
s/0\+\([0-9]\{3\}\)/\1/g;p' 37222835.txt

给:

Jumpstart Server jumo     010.020.005.126 010.029.023.024
Jumpstart Server acob     010.020.005.168 dig opt
Jumpstart Server reac     251.218.212.001 rel
NW1 H17  Node cluster     010.010.161.087
NW1 H17  Node-1       010.010.161.008
NW1 H17  Node-2       010.010.161.009
ts-nw1      010.010.008.006
Nw2 HW12 Node-3       192.168.000.001
cluster

优于@benjamin-w 提到的方法

这样可以在同一行替换多个ip地址

缺点(@benjamin-w 提到的方法解决了这个问题)

如果有一个词说Node-000234,它将更改为Node-234。事实上,您可以使用第二个替换命令来获得所需的行为。

【讨论】:

  • @sjsam 优势 2 号现已消失 ;)
  • @BenjaminW。 :我知道你会解决这个问题;)感谢您的更新。
猜你喜欢
  • 1970-01-01
  • 2010-10-08
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2016-01-20
  • 1970-01-01
相关资源
最近更新 更多