but sed command doesn't work. Output file is exactly the same as input. Generated password always starts with {SSHA} and often has special characters like "/" "+", and others...
Otherwise variables won't be expanded. Second thing is that you need to find character that is never used in generated password and use it as regex delimiter:
Be careful here. From what I'm seeing you're overwriting your passfile file with the changed passwords ONLY. This means anyone who's password wasn't changed is no longer in the passfile.
I'm not real fluent with FreeBSD but you might want to see if you can use ex. It's an inline vi editor. Your statement would look like this.
print 's/'$OLDPW'/'$NEWPW'/\nwq' | ex passfile
Some Unix flavors can use echo, others use print. You can test it very easily by creating a text file like so;
Then from the command line use something like this.
# Insert a line of text after line 3 in a file.
print '3a\n'Inserted Line'\n.\n\nwq' | ex filename.txt
# Delete a line of text that contains the pattern "search string"
print 'g/'search string'/delete\nwq' | ex filename.txt
# Substitue all occurances of "this is a line" with "that is a line.
print '%s/'this is a line'/'that is a line'/g\nwq' | ex filename.txt
I find it quite handy for updating log / config / stat and many other types of files.
my script get parameter $1 from command line as user@domain.tld then grep line in passfile for this user password only
OLDPW=`grep $1 passfile | cut -d: -f2`
so now variable "OLDPW" keeps password only. Then variable "NEWPW" keeps new password generated by `dovecotpw` command, sed do replacement and writes changes do tmpfile, finally `mv` gives me a new passfile with new password for user@domain.tld only.