Linux Bash:如何在跳过key=value的特定实例时,始终替换等号后面的内容?

Linux Bash:如何在跳过key=value的特定实例时,始终替换等号后面的内容?,linux,bash,sed,awk,Linux,Bash,Sed,Awk,在配置文件中,我希望始终替换特定“key=xxxx”等号后面的内容,但跳过“key=specificvalue”的所有实例。等号后面的值可以是除“specificvalue”之外的任何值 如何在bashshell脚本中实现这一点 文件名为caConfig.txt。我需要修改的行以commonName开头,后跟空格和等号。我想用传递的参数$1替换右边的内容 commonName = supplied commonName

在配置文件中,我希望始终替换特定“key=xxxx”等号后面的内容,但跳过“key=specificvalue”的所有实例。等号后面的值可以是除“specificvalue”之外的任何值

如何在bashshell脚本中实现这一点

文件名为caConfig.txt。我需要修改的行以commonName开头,后跟空格和等号。我想用传递的参数$1替换右边的内容

commonName                      = supplied

commonName                      = supplied

commonName                      = walmart-sam.local.lan

我需要跳过前两行,修改第三行中的内容。我不希望依赖于行的顺序。

最好使用awk:

awk -F '[= ]+' -v name="$k" -v value="$v" '$1==name{$2=value}1' file
其中,
$k
表示要替换的键,
$v
表示要更新的值

  • 此awk使用字段分隔符作为正则表达式
    '[=]+'
    ,表示1个或多个
    =
    或空格

    • 最好使用awk:

      awk -F '[= ]+' -v name="$k" -v value="$v" '$1==name{$2=value}1' file
      
      其中,
      $k
      表示要替换的键,
      $v
      表示要更新的值

      • 此awk使用字段分隔符作为正则表达式
        '[=]+'
        ,表示1个或多个
        =
        或空格

        • 我想说使用AWK:

          awk -v a="$1" '/^commonName/ && $3 != "supplied" { $3=a } { print }' caConfig.txt
          
          对于以“commonName”开头的任何行,如果原始值未“提供”,则将第三列交换为
          $1

          您可以将
          1
          ,而不是
          {print}
          打印每一行:

          awk -v a="$1" '/^commonName/ && $3 != "supplied" { $3 = a } 1' caConfig.txt
          
          如果要修改文件,可以使用间接寻址:

          awk 'commands' > tmp && mv tmp caConfig.txt
          
          或者,如果您的gawk>=4.1.0版本,则可以使用inplace模块:

          awk -i inplace 'commands' caConfig.txt
          

          我想说使用AWK:

          awk -v a="$1" '/^commonName/ && $3 != "supplied" { $3=a } { print }' caConfig.txt
          
          对于以“commonName”开头的任何行,如果原始值未“提供”,则将第三列交换为
          $1

          您可以将
          1
          ,而不是
          {print}
          打印每一行:

          awk -v a="$1" '/^commonName/ && $3 != "supplied" { $3 = a } 1' caConfig.txt
          
          如果要修改文件,可以使用间接寻址:

          awk 'commands' > tmp && mv tmp caConfig.txt
          
          或者,如果您的gawk>=4.1.0版本,则可以使用inplace模块:

          awk -i inplace 'commands' caConfig.txt
          

          如果你想坚持sed

          sed "s/^\([^ ]* *\)=.*/\1= $1/g"
          

          如果$1不包含任何sed特殊字符,则可以使用。

          如果您想继续使用sed

          sed "s/^\([^ ]* *\)=.*/\1= $1/g"
          


          只要$1不包含任何sed特殊字符,该选项就可以使用。

          谢谢大家的回复。看起来awk可能是更安全的解决方案。在您的示例中,没有第二列被“提供”的情况,我已经更新了问题。谢谢汤姆,谢谢大家的回复。看起来awk可能是更安全的解决方案。在您的示例中,没有第二列被“提供”的情况,我已经更新了问题。谢谢Tom。我要试试这个,因为我确实有两个这个键的实例需要跳过:
          awk-F'[=]+'-v name=“commonName”-v value=“$1”($1==name)和($2!=“提供的”){$2=value}1'caConfig.txt
          Hmm我会遇到麻烦吗,因为我有$1对awk和bash有特殊意义?我发现我需要添加一个测试,以跳过值为“提供”的密钥实例。我试图这样做,但失败了。我将尝试这样做,因为我确实需要跳过两个此键的实例:
          awk-F'[=]+'-v name=“commonName”-v value=“$1”($1==name)和($2!=“提供的”){$2=value}1'caConfig.txt
          Hmm我会遇到麻烦吗,因为我有$1对awk和bash有特殊意义?我发现我需要添加一个测试,以跳过值为“提供”的密钥实例。我试图这么做,但失败了。汤姆,你如何修改它,使它跳过任何匹配的键,其中值等于“提供的”?我发现有两行commonName=已提供,我需要跳过。结尾的1是什么?很有趣。谢谢试一试,还没有。也许FS需要修改为有空格和相等的值?好的,第一次通过时我去掉了-v。现在我离开了-v,我可以看到输出是正确的,但是文件没有改变。这是你期望的吗?谢谢你的帮助。Tom,你如何修改它,使它跳过任何匹配的键,其中值等于“提供的”?我发现有两行commonName=已提供,我需要跳过。结尾的1是什么?很有趣。谢谢试一试,还没有。也许FS需要修改为有空格和相等的值?好的,第一次通过时我去掉了-v。现在我离开了-v,我可以看到输出是正确的,但是文件没有改变。这是你期望的吗?谢谢你的帮助。