我的结果变量包含以下内容:
auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=888
auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888
我想替换整行,而我正在使用sed。替换似乎可以在第一次迭代中正常工作,但在第二次迭代中无效。但是,当我打印这些值时,它表明新值已正确更新。
echo "$result" |
while IFS= read -r line;
do
newValue=""
for ii in $line
do
if [[ "$ii" != *"unlock_time"* ]]; then
newValue="$newValue $ii"
fi
done
newValue="$newValue unlock_time=900"
sed -i "s/$line/$newValue/g" $password_auth
echo " Line : [ $line ]"
echo "newValue : [ $newValue ]"
done
输出显示以下内容:
Line : [ auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
newValue : [ auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
Line : [ auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888 ]
newValue : [ auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
在这里显示时,我看到变量中存在正确的值,并且所有打印都在sed命令之后进行,并且在输出中打印之前我没有看到错误。
但是当我检查文件时,我看到的第二个实例unlock_time仍然是888而不是900。
注意:我无法全局替换unlock_time,这就是为什么我存储需要更新结果的行。
循环中是否有任何被忽略的东西?
更新: 我尝试在命令行上运行sed命令:
sed -i "s/auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900/auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=999/g" temp <-- This works
sed -i "s/auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=9/auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=900/g" temp <-- This doesn't update file but doesn't throw an error either
当我在[default = die]周围放置转义字符时,该命令在命令行上有效。但是,如果我通过脚本来执行该操作呢?
答案 0 :(得分:1)
您正试图找到一个常数。通过多层报价进行正则表达式匹配的方式越来越麻烦。这是一个更简单的perl方法(出于演示目的,打包在bash中):
#!/bin/bash
result="auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=888
auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888"
# create a file to play with
echo "$result" > testfile
echo "$result" | perl -i -pe '
BEGIN { @find = <STDIN> }
for $str (@find) {
s/(\bunlock_time)=\d+/$1=900/ if $_ eq $str;
}
' testfile
# check the result
cat testfile
-i
像sed一样进行就地编辑-p
包装while循环以读取每一行,因此不需要显式的行,并在可能的修改(有点像sed)后打印出该行BEGIN
部分初始化要从(结果中)查找的字符串数组$_
)的每一行,for
将其与所有字符串进行比较,并且if
存在文字匹配(eq
),进行正则表达式搜索并替换unlock_time参数