使用sed格式化IP

时间:2016-05-14 05:13:30

标签: bash sed ip

我试图弄清楚如何使用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的情况,而且由于某种原因,它会在第3个八位字节的末尾附加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

2 个答案:

答案 0 :(得分:5)

仅改变一部分线条的惯用方法是将其复制到保留空间,从图案空间中移除我们不感兴趣的部分,然后取回保持空间,然后重新排列图案空间以替换部分我们已经改变了我们的新版本。

这应该有效(将-r替换为-E用于BSD sed):

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保持不变。

答案 1 :(得分:3)

$ 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。实际上,您可以使用第二个替换命令来获得所需的行为。