如何使用 sed 更改我的配置文件,并使用灵活的键和值?

2024-10-11 08:36:00
admin
原创
73
摘要:问题描述:我想在配置文件中搜索此表达式:“central.database”。然后我想将与“central.database”相关的设置更改为“SQLTEST”。配置文件的布局最初看起来像这样:central.database = SQLFIRSTTEST 这是我希望 sed 替换后的样子:central.d...

问题描述:

我想在配置文件中搜索此表达式:“central.database”。然后我想将与“central.database”相关的设置更改为“SQLTEST”。

配置文件的布局最初看起来像这样:

central.database = SQLFIRSTTEST

这是我希望 sed 替换后的样子:

central.database = SQLTEST

我正在 bash 脚本中执行此操作,欢迎提供任何建议、推荐或替代解决方案!

(实际上这里的central.database和都SQLTEST来自 bash 变量。)


我当前的代码(第三次尝试):

sshRetValue=$(ssh -p "35903" -i $HOME/sshids/idrsa-1.old ${1} <<EOF
        sed -i "s/^($CENTRAL_DB_NAMEs*=s*).*$/$CENTRAL_DB_VALUE/" /home/testing.txt;
        echo $?
EOF
)

错误信息:

Pseudo-terminal will not be allocated because stdin is not a terminal.
sed: -e expression #1, char 58: unknown option to `s'
-bash: line 3: EOF: command not found

解决方案 1:

sed -i -e '/central.database =/ s/= .*/= new_value/' /path/to/file

解释:

  • -i告诉 sed 将结果保存到输入文件。如果没有它,sed 将把结果打印到 stdout。

  • /central.database =/匹配包含斜杠之间的字符串的行:central.database =.由于它是正则表达式中的特殊字符,因此被转义。

  • 部分s/OLD/NEW/执行替换。OLD 字符串是要匹配的正则表达式,部分NEW是要替换的字符串。

  • 在正则表达式中,.*表示“匹配任何内容”。因此= .*匹配等号、空格,然后是其后的任何其他内容。

解决方案 2:

这是一个示例表达式:

sed -i 's/^(central.databases*=s*).*$/SQLTEST/' file.cfg

如果您想要匹配/其中的内容,您可以使用另一个分隔符:

sed -i 's#^(cent/ral.data/bases*=s*).*$#SQL/TEST#' file.cfg

或者使用变量扩展:

VAL="SQLTEST"
sed -i "s/^(central.databases*=s*).*$/$VAL/" file.cfg

在您的示例中:

sshRetValue=`sed -i "s/^($CENTRAL_DB_NAMEs*=s*).*$/$CENTRAL_DB_VALUE/" /home/testing.txt`;

$CENTRAL_DB_NAME 前面有一个 1,这是无效的。此外,sed 不会打印其返回值。这是检查返回值的首选方法:

sed -i "s/^($CENTRAL_DB_NAMEs*=s*).*$/$CENTRAL_DB_VALUE/" /home/testing.txt;
sed_return_value=$?

最后通过管道传输到 ssh(未经测试):

sed_return_value=$(ssh server <<EOF
    sed -i "s/^($CENTRAL_DB_NAMEs*=s*).*$/$CENTRAL_DB_VALUE/" /home/testing.txt;
    echo $?
EOF
)

-i 用于替换输入文件中的数据。否则 sed 将写入 stdout。

正则表达式本身就是一个领域。在 stackoverflow 答案中不可能深入解释它们,除非你无法理解某些特定功能。

解决方案 3:

我知道现在回答这个问题已经太晚了,但我想和大家分享我的知识。我曾经使用过一种非常通用的方法来解决类似的问题。我删除了与字符串匹配的整行,并将所需的值添加到该键。对于你的问题,以下是答案

replaceValue=SQLTEST
sed -i "/central.database =/d" /home/testing.txt
echo "central.database = $replaceValue"  >> /home/testing.txt

sed 从文件中删除匹配的字符串行,紧接着的下一行将所需的键和值插入到文件。

解决方案 4:

我喜欢使用awk它,因为它很容易理解它在做什么,并且很好地处理了分隔符(=),以及必须在未注释的行上执行这一事实:

awk -v var="my_var" -v new_val="NEW VALUE"   # set the vars
    'BEGIN{FS=OFS="="}                        # set separator to =
     match($1, "^\s*" var "\s*") {          # check if it matches
         $2=" " new_val                       # if so, replace the line
     }1' conf_file                            # print all lines

它用于match()检查模式是否出现在任何给定的行中。如果出现,则使用给定的值执行替换。

例如:

$ cat conf
hello
my_var= SOME VALUE
#my_var = ANOTHER VALUE
bye

我们将 中的值更改my_varNEW VALUE

$ awk -v var="my_var" -v new_val="NEW VALUE" 'BEGIN{FS=OFS="="}match($1, "^\s*" var "\s*") {$2=" " new_val}1' conf
hello
my_var= NEW VALUE
#my_var = ANOTHER VALUE
bye

还可以设置 shell 变量的值,然后使用它们-v

$ var="my_var"
$ new_value="NEW VALUE"
$ awk -v var="$var" -v new_val="$new_value" 'BEGIN{FS=OFS="="}match($1, "^\s*" var "\s*") {$2=" " new_val}1' conf

当然,你可以把所有这些放在一个 shell 函数中,然后正常调用它:

#!/bin/bash

replace () {
   file=$1
   var=$2
   new_value=$3
   awk -v var="$var" -v new_val="$new_value" 'BEGIN{FS=OFS="="}match($1, "^\s*" var "\s*") {$2=" " new_val}1' "$file"
}

# Call the replace() function with the necessary parameters
replace "conf" "my_var" "NEW VALUE" 

执行后,返回

hello
my_var= NEW VALUE
#my_var = ANOTHER VALUE
bye

同时你也可以让脚本以如下方式接收参数:./script.sh "conf_file" "var_to_replace" "NEW VALUE"然后将它们传递给函数。

解决方案 5:

如果您想在两个属性文件之间进行替换,您可以使用以下命令:

awk -F= 'NR==FNR{A[$1]=$2;next}$1 in A{$2=A[$1]}1' OFS='=' /tmp/masterfile /opt/props/finalfile.properties > /tmp/tmp.txt && mv -f /tmp/tmp.txt /opt/props/finalfile.properties

解决方案 6:

我有一个名为“config.php”的文件,我想更改其中的一行定义。

例如,以下行:

define('SOME_CONSTANT', 'old_value');

必须用这个替换:

define('SOME_CONSTANT', 'new_value');

所以我这样做了:

sed -i -e "/.*SOME_CONSTANT*./ s/.*/define('SOME_CONSTANT', 'new_value');/" path/to/config.php

在第一部分中,我正在寻找包含“SOME_CONSTANT”的行(因此是通配符)

然后我用新的定义替换该行,例如:define('SOME_CONSTANT', 'new_value');

在 Centos 7 上测试并运行良好

解决方案 7:

示例

假设我们想要更新 Postgres 配置文件以增加连接数。

我们想要更新此行/var/lib/postgresql/data/postgresql.conf

max_connections = 100

使用 sed:

sed -i 's/max_connections = 100/max_connections = 250/g' /var/lib/postgresql/data/postgresql.conf

在更新 Docker 配置文件时这非常有用,因为任何更新都需要自动化。

解决方案 8:

我使用这个脚本来保持优先级。

参数 $1 将具有存在多个配置文件的文件夹。$2 将具有需要在 $1 路径和子路径文件中替换的属性,#3 将具有需要在 $2 之上覆盖的属性

它还具有隐藏的逻辑来检查环境变量是否存在,因为键存在于 $2 和 $3 中,并优先考虑该变量。

即如果环境中存在一个密钥,则该密钥具有最高优先级。其次是 $3,再其次是 $1 文件。

#!/bin/bash
#Usage is propertyReplacer <CONFIG_FOLDER_PATH> <CONFIG_FILE_2ND_PRIORITY> <CONFIG_FILE_1ST_PRIORITY>
function propertyReplacer() {

  filePathToAct="$1"
  propertiesFilePath="$2"
  propertiesSecureFilePath="$3"

  declare -A keyValues

  while IFS='=' read -r key value; do
    if [  "$key" == "" ]; then
      continue
    elif [[  "$key" =~ ^#.*$ ]]; then
      continue
    else
      echo $key " --> " $value
      keyValues[$key]=$value
    fi
  done < "$propertiesFilePath"

  if [ ! -f "$propertiesSecureFilePath" ]; then
    continue
  else
    while IFS='=' read -r key value; do
      if [  "$key" == "" ]; then
        continue
      elif [[  "$key" =~ ^#.*$ ]]; then
        continue
      else
        echo $key " --> " $value
        keyValues[$key]=$value
      fi
    done < "$propertiesSecureFilePath"
  fi

  for key in ${!keyValues[@]}; do
    envProp=${key//[@]/}
    if [  "$(eval echo '$'$envProp)" == "" ]; then
      echo "Environment key not exist" $envProp
    else
      value=$(eval echo '$'$envProp)
      echo "From Environment " $envProp " --> "$value 
      keyValues[$key]=$value
    fi
  done 


find "$filePathToAct" | while read -r resultFileName; do
  if [ ! -f "$resultFileName" ]; then
    continue
  else
    echo "Acting on the file $resultFileName"

    for key in ${!keyValues[@]}; do
      value=$(echo "${keyValues[${key}]}" | sed 's///\//g')
      echo "sed -i 's/$key/$value/g' $resultFileName "
      eval "sed -i 's/$key/$value/g' $resultFileName "
    done 
  fi
done 

} 
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用