正则表达式在sed中替换特定的字符串



我有一个config.txt文件,它由以下行组成

$ cat config.txt | head -n 3
f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@192.168.3.4:26601
be9d757acee1f5b573ec18d1e056542bc282be23@169.172.56.77:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.129.101.3:26607
$ cat ip.txt | head -n 3
10.0.4.5
10.3.5.6
10.3.5.8

我想把config.txt上的IP地址分别替换为IP .txt文件上的IP地址

期望的输出是

f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@10.0.4.5:26601
be9d757acee1f5b573ec18d1e056542bc282be23@10.3.5.6:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.3.5.8:26607

由于配置文件中的ip是动态的,我需要在sed中使用正则表达式来替换ip。例如:

$ echo "f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@192.168.3.4:26601" | sed "s/*@+:*/*@10.0.4.5:*/g"

但是它没有更新ip。我对脚本中的正则表达式非常陌生。请帮助!

嗯,在这种情况下可以使用sed和正则表达式。您可以首先将文件连接起来,然后使用regex对行进行洗牌:

paste config.txt ip.txt | sed 's/@[^:]*(.*)t(.*)/@21/'

注意,sed只在一行上下文中工作。但是正则表达式不是"动态的",如果是the ip's in config file are dynamic,那么你应该使用一些"更多"的东西。然后是regex,最好是一个支持映射和内部状态的完整编程语言,比如awk,还有perlpython

一种使用awk代替的方法。它首先读取ip.txt并将其内容存储在按行号索引的数组中,然后对于config.txt的每一行,将其中的IP地址替换为ip.txt对应行的IP地址:

$ awk 'FNR==NR { ips[FNR] = $0; next }
{ sub(/@[^:]+:/, "@" ips[FNR] ":"); print }' ip.txt config.txt
f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@10.0.4.5:26601
be9d757acee1f5b573ec18d1e056542bc282be23@10.3.5.6:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.3.5.8:26607

另一种说法:

paste -d~ config.txt ip.txt | while IFS="~" read config ip; 
do
echo $config | sed -r "s/([a-z0-9]+)@(([0-9]{1,3}.?){4})(:[0-9]+)/1@$ip4/g";
done;

这是一个纯粹的答案。我评论了一下。把内容放到我的。Sed和叫Sed -n -f my。Sed config.txt ip.txt

# We concat config.txt and ip.txt to a single line like
# f...c@192.168.3.4:26601|b...3@169.172.56.77:26604|d...7@10.129.101.3:26607|;10.0.4.5;10.3.5.6;10.3.5.8
# the characters "|" and ";" are used as separators
# the records of config.txt are identified by @,
# those of ip.txt the pattern ^[0-9](.[0-9]){3}
# if it's a config.txt line append "|" and append it to the hold space
/@/ {
s/$/|/
H
}
# if it's a ip.txt line put a ";" before it and append it to the hold space
/^[0-9]+(.[0-9]+){3}/ {
s/^/;/
H
}
# Now the two files are read. We do the replacements at the end of input
$ { 
x
# after having deleted all newlines the pattern spaces consists
# of one line as mentioned above
s/n//g
:b
# now we replace recursively the ip adress in the first "|"
# limited column by the ip adress in
# the first ";" limited column. (:b ist the beginning of the loop) 
# 1. group: sequence of not | characters ended by @<ip-adress>:<not | characters>
# 2. group: the characters including the "@"
# 3. group: part of the ip adress pattern
# 4. group: the characters from : to "|" (excluded)
# 5. group: the sequence of not ";" characters followed by ";"
# 6. group: the replacement ip adress
# 7. group: part of the replacement ip adress pattern
# The "," in the replacement replaces the first "|" in order
# to enable recursion (see 1. group above)
s/(([^|]*@)[0-9]+(.[0-9]+){3}(:[^|]*))|([^;]*);([0-9]+(.[0-9]+){3})/264,5/
tb
# replace all , except the last one with newlines
s/,(.)/n1/g
# replace the last ","
s/,//
p
}

这可能适合您(GNU sed &猫):

cat -n ipFile | sed -E 's/t(.*)/s#@.*:#@1:#/' | sed -f - configFile

为ipFile添加行号

将ipFile中的每一行替换为ip地址的sed替换命令

使用configFile作为源调用第二个sed应用程序,并对文件中的每一行应用ipFile中的替换命令。

注意:-f选项接受来自文件的sed命令,在此强制转换中,该文件是-从前面的sed应用程序通过管道传输的。


另一个解决方案:

paste configFile ipFile | sed -E 's/@.*:(S*)t(S+)/@2:1/;/@/!d'

这将替换configFile中附加的ip地址。

注意:如果ipFile比configFile有更多的行,/@/!d将确保不包括额外的行。

最新更新