我想用另一個替換文件中的一個字符串,更具體地說,替換dovecot passwd文件(/etc/dovecot/passwd
)中的用戶名:密碼條目,但只有當記錄存在時。sed搜索和替換的文件,只存在模式
所以,我需要什麼:
sed
命令- ,做什麼,如果記錄不存在(見dovecot的passwd文件的例子)
- ,在文件替換(如果沒有很好的原因outputing到新的文件和移動新文件原件)
這裏是/etc/dovecot/passd
例如:
[email protected]:{CRAM-MD5}479375185777b7ba573747c111483bdd628332a70268ce283dc80bedd0f65988
[email protected]:{CRAM-MD5}10b7176649d8bb3eb38f6b68a0c6c826ffab5656181821e598296ebd31e8f64f
和我到目前爲止已經試過(創建新的文件,輸出到新mv
原始即使記錄不存在)
#!/usr/bin/env php
<?php
$passwd_file = '/etc/dovecot/passwd';
$time = time();
$newtempfile = '/tmp/' . $time . 'dvctpwd';
/**
* $search generates replace target [email protected]:{CRAM-MD5}479375185777b7ba573747c111483bdd628332a70268ce283dc80bedd0f65988
* if [email protected] gives correct password to dovecot's doveadm pw -u [email protected] -poldpassword
**/
$search = $argv[1] .':' . exec("doveadm pw -u " . $argv[1] . " -p" . $argv[2]);
/**
* $replace generates replace value [email protected]:{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;
參見:如何更換一個特定的行在一個文本文件中使用php?](http://stackoverflow.com/q/3004041/3776858) – Cyrus
避免sed的「in-file」支持的一個原因是它不是真正的文件中; sed模仿使用臨時文件的文件內行爲,所以你唯一的好處是簡化的代碼,而如果文件系統填滿了,或者也可能與其他情況一起增加了問題的風險。我喜歡在幾乎所有命令上編寫包含錯誤處理的腳本,這樣如果出現問題,我可以在腳本中採取適當的操作。 – ghoti
@ghoti好點。我懷疑實際的替換不是在文件本身完成的,但無論如何,我的解決方案儘可能簡單,因爲我不是BASH語言的掌握者。 –