【问题标题】:regex in sed to replace particular stringsed 中的正则表达式替换特定字符串
【发布时间】:2021-11-20 06:17:05
【问题描述】:

我有一个文件 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。我对脚本中的正则表达式非常陌生。请帮忙!

【问题讨论】:

  • 避免使用 head -n3 config.txt 对 Cat (tm) 进行无用的使用,顺便说一句。

标签: regex sed


【解决方案1】:

这可能对你有用(GNU sed 和 cat):

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

将行号添加到 ipFile。

用 sed 替换命令替换 ipFile 中的每一行以替换 ip 地址。

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

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


另一种解决方案:

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

这将替换配置文件中附加的 IP 地址。

注意如果 ipFile 的行数多于 configFile,/@/!d 将确保不包含其他行。

【讨论】:

    【解决方案2】:

    这是一个纯粹的 sed 答案。我评论了它。将内容放到 my.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\}\)/\2\6\4,\5/
        tb
        # replace all , except the last one with newlines
        s/,\(.\)/\n\1/g
        # replace the last ","
        s/,//
        p
    }
    

    【讨论】:

      【解决方案3】:

      另一种方式:

      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@$ip\4/g";
      done;
      

      【讨论】:

        【解决方案4】:

        好吧,在这种情况下可以使用sed 和正则表达式。您可以首先加入文件,然后然后使用正则表达式来打乱

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

        请注意,sed仅一行的上下文中有效。但是正则表达式不是“动态的”,如果the ip's in config file are dynamic 那么你应该使用“更多”而不是正则表达式,更好的是支持映射和内部状态的完整编程语言,比如awk,还有perlpython .

        【讨论】:

          【解决方案5】:

          一种使用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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-19
            • 2012-12-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-10
            相关资源
            最近更新 更多