次の式の構成ファイルを検索したい:「central.database」。次に、「central.database」に関連付けられている設定を「SQLTEST」に変更します。
構成ファイルのレイアウトは、最初は次のようになります。
central.database = SQLFIRSTTEST
これは、sed交換後の外観です。
central.database = SQLTEST
これはbashスクリプトで行っています。提案、推奨事項、または代替ソリューションは歓迎します。
(実際には両方central.database
およびSQLTEST
は、ここではbash変数から取得されます。
私の現在のコード(3回目の試行):
sshRetValue=$(ssh -p "35903" -i $HOME/sshids/idrsa-1.old ${1} <<EOF
sed -i "s/^\($CENTRAL_DB_NAME\s*=\s*\).*\$/\1$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
式の例を次に示します。
sed -i 's/^\(central\.database\s*=\s*\).*$/\1SQLTEST/' file.cfg
/
を含むものと一致させたい場合は、別の区切り文字を使用できます。
sed -i 's#^\(cent/ral\.data/base\s*=\s*\).*$#\1SQL/TEST#' file.cfg
または、変数展開の場合:
VAL="SQLTEST"
sed -i "s/^\(central\.database\s*=\s*\).*\$/\1$VAL/" file.cfg
あなたの例では:
sshRetValue=`sed -i "s/^\(\1$CENTRAL_DB_NAME\s*=\s*\).*\$/\1$CENTRAL_DB_VALUE/" /home/testing.txt`;
$ CENTRAL_DB_NAMEの前に無効な\ 1があります。また、sedは戻り値を出力しません。これは、戻り値を確認するための好ましい方法です。
sed -i "s/^\($CENTRAL_DB_NAME\s*=\s*\).*\$/\1$CENTRAL_DB_VALUE/" /home/testing.txt;
sed_return_value=$?
そして最終的にはsshへのパイピング(テストされていません):
sed_return_value=$(ssh server <<EOF
sed -i "s/^\($CENTRAL_DB_NAME\s*=\s*\).*\$/\1$CENTRAL_DB_VALUE/" /home/testing.txt;
echo $?
EOF
)
-iは、入力ファイルのデータを置き換えるためのものです。それ以外の場合、sedはstdoutに書き込みます。
正規表現は独自のフィールドです。あなたを避けている特定の機能がない限り、stackoverflowの答えでそれらを詳細に説明することは不可能でしょう。
sed -i -e '/central.database =/ s/= .*/= new_value/' /path/to/file
説明:
-i
は、結果を入力ファイルに保存するようにsedに指示します。 sedを使用しないと、結果が標準出力に出力されます。/central.database =/
は、スラッシュの間に文字列を含む行、つまり「central.database = "」に一致します。s/OLD/NEW/
部分は sub責。 OLD文字列は一致する正規表現であり、NEW
部分は置換する文字列です。.*
は「すべてに一致」を意味します。そう = .*
は、等号、スペース、およびその後のその他のものと一致します。この質問に答えを追加するのは遅すぎることを知っていますが、皆さんに私の知識を共有したいと思いました。同様の問題を解決するために私が従った非常に一般的なアプローチがあります。文字列に一致する行全体を削除し、そのキーに必要な値を追加しました。あなたの質問に対する答えはここにあります
replaceValue=SQLTEST
sed -i "/central.database =/d" /home/testing.txt
echo "central.database = $replaceValue" >> /home/testing.txt
sedは一致する文字列行をファイルから削除し、すぐ次の行が必要なキーと値をファイルに挿入します。
これには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_var
_の値を_NEW 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
_
シェル変数に値を設定し、それらを_-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
_
もちろん、これらすべてをシェル関数内に配置して、通常どおり呼び出すことができます。
_#!/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"
_を使用して関数に渡します。
2つのプロパティファイルを置き換えたい場合は、これを使用できます。
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
このスクリプトを使用して、優先順位を維持しました。
引数$ 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
}