![使用不同的值替换文件中的字符串以替换相同的模式](https://linux22.com/image/77961/%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%E5%80%BC%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BB%A5%E6%9B%BF%E6%8D%A2%E7%9B%B8%E5%90%8C%E7%9A%84%E6%A8%A1%E5%BC%8F.png)
我的里面有这样的字符串/etc/mail/virtusertable
[email protected] error:nouser Account temporary disabled
[email protected] error:nouser Account temporary disabled
[email protected] error:nouser Account temporary disabled
我想用我能从中得到的error:nouser Account temporary disabled
适当的内容替换所有内容virtuser_NNN
/etc/dovecot/dovecot.passwd
我尝试了不同的变体,但结果都相同。全部error:nouser Account temporary disabled
替换为第一个virtuser_NNN
来自/etc/dovecot/dovecot.passwd
运行我的脚本后,它看起来像
[email protected] virtuser_1
[email protected] virtuser_1
[email protected] virtuser_1
我的脚本是:
cat /etc/mail/virtusertable_back | grep example.com |
grep 'error:nouser Account temporary disabled' | awk '{print $1}' |
xargs -I{} grep {} /etc/dovecot/dovecot.passwd | awk -F'::' '{print $2}' |
xargs -I{} sh -c 'grep {} /etc/passwd' | awk -F: '{print $1}'|
xargs -n1 -P1 -I{} sed -i 's/error\:nouser Account temporary disabled/{}/' /etc/mail/virtusertable_back
是的,我正在 的副本上执行此操作/etc/mail/virtusertable
。
并且/etc/dovecot/dovecot.passwd
有这样格式的记录:
[email protected]:*$1$hash here:user id:group id::/var/www/userlogin/data/email/example.com/mail:::/var/mail/virtuser_NNNN
需要补充的是,我想将带有错误消息的字符串更改为仅适用于特定邮件域的适当虚拟机,而不是整个文件。
答案1
我会用 Perl 来做这件事。将电子邮件和关联的用户名保存在/etc/dovecot/dovecot.passwd
哈希中,然后替换为/etc/mail/virtusertable
:
$ perl -i -ape 'BEGIN{
open($fh,"/etc/dovecot/dovecot.passwd");
while(<$fh>){ @G=split(/:/); $k{$G[0]}=$G[2]; }
}
s/error:nouser Account temporary disabled/$k{$F[0]}/ if defined $k{$F[0]};
' /etc/mail/virtusertable > newfile
解释
使-i
perl 就地编辑其输入文件,与sed -i
.这-a
使得它将空白处的每个输入行分割到数组中@F
。就像awk
。意思-p
是“在应用由”给出的脚本后打印每一行-e
。
脚本本身读取/etc/dovecot/dovecot.passwd
块BEGIN{}
(因此在读取输入文件之前/etc/mail/virtusertable
),将每一行拆分:
到数组中@G
,然后将每封电子邮件保存为散列中的键,%k
其值为用户名。
完成后,它将继续处理并用与第一个字段中的电子邮件相对应的用户名(如果定义了该用户名)/etc/mail/virtusertable
替换每个用户名。error:nouser Account temporary disabled
答案2
如果其中没有反斜杠,以下管道应该可以正常工作virtuser_NNN名称:
tbl=/etc/mail/virtusertable
pw=/etc/dovecot/dovecot.passwd
cut -d: -f1 "$pw" |
grep -Fnf- "$tbl"|
sed -e's|:.*/\(.*\)|s/:nouser/:\1/|' |
sed -f- "$tbl"
它会:
首先
cut
去掉每行除第一个非冒号字符序列之外的所有字符dovecot.passwd
grep
对于-F
固定字符串匹配的结果virtusertable
s///
将这些结果中除了行号和最后出现的非斜杠字符序列之外的所有字符替换为字符串,例如:[LINENO]
s/:nouser/:
not-slashes
/
最后使用那输出为
sed
脚本virtusertable