【问题标题】:sed/awk look for pattern in string and change another pattern on the same linesed/awk 在字符串中查找模式并在同一行更改另一个模式
【发布时间】:2018-02-24 10:32:23
【问题描述】:

我有一个 F5 bigip.conf 文本文件,我想在其中将所有显示“10.166.201”的行的路由域从 701 更改为 703。路由域由%701表示

10.166.201.10%701
10.166.201.15%701
10.166.201.117%701

我可以用 bash 做到这一点,但问题是“else printf”命令(我也尝试过 echo),它应该打印出所有其他行,错误地解析了诸如“\r\n”之类的东西" 并将它们保留为 "rn"

#!/bin/bash

while read line
do
if [[ $line = *"10.166.201"* ]]; 
    then
printf '%s\n' "$line" | sed -e 's/701/703/'

else printf '%s\n' "$line"  

fi  

done < bigip.conf > bigip.conf_updated

有没有办法阻止 printf 和 echo 修改“\r\n”?

在 sed/awk 中有没有更好的方法来做到这一点?

谢谢。

【问题讨论】:

  • 哦,伙计,您的 Input_file 中也有 \r,如果您想删除它们,那么我在帖子中也添加了该解决方案。

标签: bash awk sed


【解决方案1】:

使用regexp address

sed '/10\.166\.201\./s/%701/%703/' bigip.conf

一旦您确定该命令对您有效,您就可以使用 -i 更改文件:

sed -i'' '/10\.166\.201\./s/%701/%703/' bigip.conf

使用 GNU sed,您可以省略 -i 的选项值:

sed -i '/10\.166\.201\./s/%701/%703/' bigip.conf

【讨论】:

  • 谢谢。如果我想将它放在另一个 IP 搜索和路由域更改的脚本中,我可以使用 sed -i '/10\.166\.201\./s/701/703/' - i '/10\. 165\.202\./s/702/704/' ?
  • 差不多。应该是sed -i -e '/10\.166\.201\./s/701/703/' -e '/10\.165\.202\./s/702/704/'
  • 考虑如果输入是10.166.201.701%35110.166.201.10%701 会做什么。
  • 那是10.166.203.189 吗? :)
  • @EdMorton 是的,我正在考虑这个问题,但由于 701 > 255 应该没问题。但是你是对的,当输入 701 变为 123 时,这确实是一个问题。我把命令改成s/%701/%703/
【解决方案2】:

sed:

sed -E 's/(10\.166\.201\.[[:digit:]]+%70)1/\13/'
  • 捕获的组,(10\.166\.201\.[[:digit:]]+%70) 匹配 10.166.201. 字面意思,然后是一个或多个数字,然后是 %70 字面意思

  • 在捕获的组之外,1 匹配字面;在替换中,使用捕获的组并将1替换为3

示例:

% cat file.txt
10.166.201.10%701
10.166.201.15%701
10.166.201.117%701

% sed -E 's/(10\.166\.201\.[[:digit:]]+%70)1/\13/' file.txt
10.166.201.10%703
10.166.201.15%703
10.166.201.117%703

【讨论】:

    【解决方案3】:

    关注awk 可能对您有所帮助。

    awk '{gsub(/\r/,"")} /your_string/{sub(/701/,"703")} 1'   Input_file
    

    如果您想将输出保存到相同的 Input_file 本身,请执行以下操作:

    awk '{gsub(/\r/,"")} /your_string/{sub(/701/,"703")} 1'  Input_file > temp_file && mv temp_file  Input_file
    

    编辑:如果您的 Input_file 中包含 \r,那么我在上面的代码中添加了 {gsub(/\r/,"")},以防万一您没有它们,您可以从代码中删除它们。

    EDIT2: 将字符串更改为 your_string 也会在您的地址中将 . 更改为 \.

    【讨论】:

      【解决方案4】:

      清晰、简单、稳健、高效的方法是:

      awk 'BEGIN{RS=ORS="\r\n"; FS=OFS="%"} index($1,"10.166.201.")==1{ $2="703" } 1' file
      

      请注意,您无需转义 .s 或锚点以避免部分匹配,因为上面只是将 IP 地址视为出现在行首的字符串。以上使用 GNU awk 进行多字符 RS 以保留您的 \r\n 行尾。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-20
        • 2021-03-16
        • 1970-01-01
        • 1970-01-01
        • 2014-10-07
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        相关资源
        最近更新 更多