Substituindo strings no arquivo usando valores diferentes para substituir o mesmo padrão

3

Eu tenho essas strings no meu /etc/mail/virtusertable

[email protected]    error:nouser Account temporary disabled
[email protected]    error:nouser Account temporary disabled
[email protected]    error:nouser Account temporary disabled

E eu quero substituir todo o error:nouser Account temporary disabled pelo virtuser_NNN apropriado que eu posso obter de /etc/dovecot/dovecot.passwd

Eu tentei variantes diferentes, mas todas com o mesmo resultado. Todos error:nouser Account temporary disabled foram substituídos pelo primeiro virtuser_NNN de /etc/dovecot/dovecot.passwd

Depois de executar o meu script, parece que

[email protected]    virtuser_1
[email protected]    virtuser_1
[email protected]    virtuser_1

Meu script é:

 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

Sim, estou fazendo isso na cópia de /etc/mail/virtusertable .

E /etc/dovecot/dovecot.passwd tem registros em tal formato:

[email protected]:*$1$hash here:user id:group id::/var/www/userlogin/data/email/example.com/mail:::/var/mail/virtuser_NNNN

Preciso adicionar, que eu quero alterar strings com mensagem err para virtusers apropriados apenas para um domínio de e-mail específico, não para o arquivo inteiro.

    
por Nokse 22.11.2015 / 14:56

2 respostas

2

Eu faria isso em Perl. Salve o e-mail e o nome de usuário associado do /etc/dovecot/dovecot.passwd em um hash e substitua em /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

Explicação

O -i faz o perl editar seu arquivo de entrada, o mesmo que sed -i . O -a faz com que ele divida cada linha de entrada no espaço em branco na matriz @F . Apenas como awk . O -p significa "imprimir todas as linhas depois de aplicar o script fornecido por -e ".

O próprio script lê /etc/dovecot/dovecot.passwd no bloco BEGIN{} (antes de ler o arquivo de entrada, /etc/mail/virtusertable ), divide cada linha em : na matriz @G e salva cada email como uma chave no hash %k cujos valores são os nomes de usuários.

Quando terminar, ele processará /etc/mail/virtusertable e substituirá cada error:nouser Account temporary disabled pelo nome de usuário correspondente ao email no 1º campo se esse nome de usuário for definido.

    
por 22.11.2015 / 16:13
1

O pipeline a seguir deve funcionar bem, desde que não haja barras invertidas nos nomes virtuser_NNN :

tbl=/etc/mail/virtusertable
pw=/etc/dovecot/dovecot.passwd
cut  -d:  -f1 "$pw" |  
grep -Fnf-    "$tbl"|
sed  -e's|:.*/\(.*\)|s/:nouser/:/|' | 
sed  -f-      "$tbl"

Irá:

  • primeiro cut de todos, exceto da primeira seqüência de caracteres não-dois-pontos para cada linha de dovecot.passwd

  • grep para -F ixed-string corresponde aos resultados em virtusertable

  • s/// ubstituir todos, exceto o número da linha e a última seqüência não-barra de caracteres desses resultados em uma string como:

    • [LINENO] s/:nouser/: not-slashes /
  • finalmente, use essa saída como um script sed contra virtusertable

por 22.11.2015 / 17:37