我有一个文件 ( one.cnf
) 为:
KEY1="value1"
KEY4="VALUE4"
另一个文件 ( two.cnf
) 为:
USER_HOST="local"
KEY1="abc"
PASS="lorem"
KEY2="ABC"
KEY4="XYZ"
我想从 中读取相应变量的值one.cnf
并替换two.cnf
。
所以最终two.cnf
看起来像
USER_HOST="local"
KEY1="value1"
PASS="lorem"
KEY2="ABC"
KEY4="VALUE4"
答案1
使用awk
:从文件一读取密钥,然后替换文件二:
awk 'BEGIN{FS=OFS="="}
NR==FNR {key[$1]=$2 ; next }
$1 in key {$2=key[$1]}
1' one.cnf two.cnf
如需更换,请使用sponge
awk '<code>' one.cnf two.cnf | sponge two.cnf
或者 GNUawk
就地,但这需要稍微更改代码以确保one.cnf
不被清空:
awk -i inplace 'BEGIN{FS=OFS="="}
NR==FNR {key[$1]=$2}
FNR!=NR && $1 in key {$2=key[$1]}
1' one.cnf two.cnf
用于-i inplace -v INPLACE_SUFFIX=.bup
将带有 - 后缀的原始文件.bup
作为备份。
答案2
假设文件一中的值键中没有斜杠/
字符,这是一种简单的方法。
while IFS="=" read key value; do sed -i "s/^${key}=.*/${key}=${value}/" two.cnf ; done < one.cnf
这里的问题之一是,即使两个文件中某些键的值相同,它也会更改文件。如果您想避免更改不需要更改的键的文件,您可以添加一个简单的 grep:
while IFS="=" read key value; do grep -xq "${key}=${value}" two.cnf || sed -i "s/^${key}=.*/${key}=${value}/" two.cnf ; done < one.cnf
或者没有 grep 和单个 sed 命令:
while IFS="=" read key value; do sed -i "/^${key}=/{/^${key}=${value}$/! s/^${key}=.*/${key}=${value}/}" two.cnf ; done < one.cnf
其他需要注意的事项:
- 如果第一个文件中的密钥在第二个文件中不存在,则不会添加它。
- 我假设第一个文件仅包含 key=value 形式的行,并且不包含其他类型的行。
- 另外我建议在操作之前备份第二个文件,以防出现问题。
答案3
#!/bin/bash
for val in cat one.cnf
do
KEY=`echo $val | cut -d'=' -f1`
VALUE=`echo $val | cut -d'=' -f2`
EXISTS=`grep -i "$KEY" two.cnf | grep -v grep`
if [ -n "$EXISTS" ]; then
VALUE2=`echo "$EXISTS" | cut -d'=' -f2`
echo "$VALUE-$VALUE2"
sed -i 's/'$VALUE2'/'$VALUE'/g' two.cnf
fi
done
根据您的位置更改文件路径。