我试图弄清楚如何使用sed执行以下操作:
我有一个IPv4地址列表,我试图让它们在显示屏上统一。例如:1.2.4.32
将是001.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
但是这会遇到一个更实际的问题,因为我的输入文件在其他非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
答案 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.注意
\2\1\4
(没有非捕获组)在sed)。总体输出
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
。实际上,您可以使用第二个替换命令来获得所需的行为。