我想将文件中的一个字符串替换为另一个字符串,更具体地说,在dovecot passwd文件(/etc/dovecot/passwd
)中替换username:password条目,但仅限于记录存在。
所以,我需要的是:
sed
命令以下是/etc/dovecot/passd
示例:
johndoe@example.com:{CRAM-MD5}479375185777b7ba573747c111483bdd628332a70268ce283dc80bedd0f65988
janedoe@example.com:{CRAM-MD5}10b7176649d8bb3eb38f6b68a0c6c826ffab5656181821e598296ebd31e8f64f
到目前为止我已尝试过(创建新文件,输出到新文件,mv
到原始,即使记录不存在)
#!/usr/bin/env php
<?php
$passwd_file = '/etc/dovecot/passwd';
$time = time();
$newtempfile = '/tmp/' . $time . 'dvctpwd';
/**
* $search generates replace target johndoe@example.com:{CRAM-MD5}479375185777b7ba573747c111483bdd628332a70268ce283dc80bedd0f65988
* if johndoe@example.com gives correct password to dovecot's doveadm pw -u johndoe@example.com -poldpassword
**/
$search = $argv[1] .':' . exec("doveadm pw -u " . $argv[1] . " -p" . $argv[2]);
/**
* $replace generates replace value johndoe@example.com:{CRAM-MD5}...
* i.e. scheme with new password
**/
$replace = $argv[1] .':' . exec("doveadm pw -u " . $argv[1] . " -p" . $argv[3]);
$command = <<<DD
sed -e "s|$search|$replace|" $passwd_file > $newtempfile && mv $newtempfile $passwd_file && echo "Password changed!\n";
DD;
$output = passthru($command);
echo $output . PHP_EOL;
答案 0 :(得分:1)
虽然您可以使用 sed 使用 -i 标记进行替换,但文件的上次修改时间将始终更新:
sed -i "s|$search|$replace|" "$passwd_file"
确实,请注意文件出生的时间,上次访问的时间以及上次修改的时间将使用上面的命令更新。这可以通过在上面的sed命令之前和之后执行以下命令来显示:
stat -c "%W %X %Y %Z" "$passwd_file"
此外,无论是否发生替换,上述sed命令都将返回0。
所以,如果你绝对不能更新文件,包括时间戳,你可以这样做:
grep -q "$search" "$passwd_file" &&
sed -i "s|$search|$replace|" "$passwd_file"
如果您需要显示该文件已更新的消息,您可以使用list:
grep -q "$search" "$passwd_file" &&
{
sed -i "s|$search|$replace|" "$passwd_file"
echo -e "Password changed!\n"
}
最后,如果您希望在密码未更改时显示消息,则可以执行以下操作:
grep -q "$search" "$passwd_file" &&
{
sed -i "s|$search|$replace|" "$passwd_file"
printf "Password changed!\n\n"
} || printf "Password not changed!\n\n"
要将上述内容作为一行执行,请务必在列表中添加分号,包括最后一个元素:
grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n\n"; } || printf "Password not changed!\n\n"
一些注意事项:
答案 1 :(得分:1)
使用GNU sed编辑文件&#34;就地&#34;:
a="johndoe@example.com"
md5="abc123"
sed -i 's/^'"$a"'.*/'"$a"':{CRAM-MD5}'"$md5"'/' /etc/dovecot/passd
文件/ etc / dovecot / passd中的输出:
johndoe@example.com:{CRAM-MD5}abc123 janedoe@example.com:{CRAM-MD5}10b7176649d8bb3eb38f6b68a0c6c826ffab5656181821e598296ebd31e8f64f