使用sed格式化IP

D.Z*_*Zou 10 ip bash sed

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

我得到了一个IPv4地址列表,我试图让它们在显示屏上统一.所以例如:1.2.4.32001.002.004.032.10.125.62.1会的010.125.062.001.

我正在尝试使用sed这样做,因为这就是我现在正在学习的东西.

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

sed 's/\<[0-9][0-9]\>/0&/g' file
sed 's/\<[0-9]\>/00&/g' file
Run Code Online (Sandbox Code Playgroud)

但这会遇到更实际的问题,因为我的输入文件在其他非IP地址位置会有单位或双位数字.例:

host-1 1.2.3.32
Run Code Online (Sandbox Code Playgroud)

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

sed 's/\.\<[0-9]\>/00&/g'
Run Code Online (Sandbox Code Playgroud)

但是这不仅忽略了这种情况1.something.something.something,而且00由于某种原因它也会附加在第3个八位字节的末尾.

echo "10.10.88.5" | sed 's/\.\<[0-9]\>/00&/g'
10.10.8800.5
Run Code Online (Sandbox Code Playgroud)

样本文件:

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
Run Code Online (Sandbox Code Playgroud)

Ben*_* W. 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
Run Code Online (Sandbox Code Playgroud)

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

010.020.005.126\nJumpstart Server jumo     10.20.5.126$
Run Code Online (Sandbox Code Playgroud)

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

010.020.005.126\nJumpstart Server jumo     10.20.5.126$
^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^           ^
      (.*)     \n          (.*)              \b...\b  (.*)
       \1                   \2                  \3     \4
Run Code Online (Sandbox Code Playgroud)

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

  • 有四个捕获组,但第三个是帮助描述IP地址,我们实际上并不想保留它,因此\2\1\4在替换中(sed中没有非捕获组).
  • 最后一个捕获组(在IP地址之后)是空的,但是使用它可以将其用于具有任何地址的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
Run Code Online (Sandbox Code Playgroud)

与完全不可读的单线相同:

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
Run Code Online (Sandbox Code Playgroud)

\b是GNU扩展.脚本大多数都没有它; 使用它确保blah1.2.3.4blah留下一个人.


sjs*_*sam 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
Run Code Online (Sandbox Code Playgroud)

正在做 :

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
Run Code Online (Sandbox Code Playgroud)

给出:

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
Run Code Online (Sandbox Code Playgroud)

相对于 @benjamin-w 提到的方法的优势

这可以替换同一行中的多个ip地址

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

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