使用不同的值替换文件中的字符串以替换相同的模式

使用不同的值替换文件中的字符串以替换相同的模式

我的里面有这样的字符串/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

解释

使-iperl 就地编辑其输入文件,与sed -i.这-a使得它将空白处的每个输入行分割到数组中@F。就像awk。意思-p是“在应用由”给出的脚本后打印每一行-e

脚本本身读取/etc/dovecot/dovecot.passwdBEGIN{}(因此在读取输入文件之前/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

相关内容