Comandos externos no AWK

0

Existe uma maneira de usar comandos shell do Linux dentro do awk? Eu preciso verificar a existência do usuário de um arquivo de texto (dado como) username [email protected] e escreva os que não são usuários existentes em um novo arquivo de texto como

username password [email protected]

Atualmente, tenho isto:

#!/bin/bash
awk '{
for(i=1; i<=NF; i+=2) {
    pass='pwgen'
    if(id -u $i | awk '{$1}' > 999) print $1;
    else $i pass $i,'@email.com' >> newusers.txt
}
}' $*

Eu acho que deveria funcionar, mas obviamente não funciona. Ele deve criar uma nova senha usando o alias pwgen (que cria 1 senha por uso), verifique se o elemento $ i no arquivo de texto é um usuário existente, comparando a saída de id -u $ i | awk '{$ 1}' a 999 e se não for mais de 999, deve acrescentar username password [email protected] a um arquivo de texto chamado newusers.txt.

    
por Tõnis Piip 14.03.2017 / 12:21

1 resposta

2

Seu script do awk

{
for(i=1; i<=NF; i+=2) {
    pass=pwgen
    if(id -u $i | awk {ARG1} > 999) print $1;
    else $i pass $i,@email.com >> newusers.txt
}
}

onde ARG1 é o primeiro argumento passado para o script de shell. A primeira aspa simples em seu script de shell inicia um literal com aspas simples que termina com a segunda aspa simples, ou seja, após | awk { . A terceira cota simples inicia outro literal com aspas simples, que termina com a quarta cota simples, etc. Se você deseja incluir uma cota única, é necessário citar a citação. Mas aqui você não precisa de uma única citação no script awk de qualquer maneira. Uma string no awk precisa ser escrita entre aspas duplas.

pass=pwgen

Esta linha de código awk define a variável pass com o valor da variável pwgen . Como pwgen não está definido, pass está definido como um valor vazio.

Você supostamente quis escrever pass='pwgen' , que é a sintaxe do shell para definir a variável pass da shell para a saída do comando pwgen . Mas esta é a sintaxe do shell, não awk, então não é surpresa que não funcione no awk. Você pode ler a saída de um comando no awk com a sintaxe do pipe:

pwgen | getline pass;
close("pwgen");

Você precisa fechar o pipe, caso contrário, a próxima vez que a instrução for executada, ele será lido no mesmo canal em vez de executar uma nova instância de pwgen .

    if(id -u $i | awk '{$1}' > 999) print $1;

Você pode usar a função system para executar um comando shell. O comando awk embutido que você escreveu não faz sentido. Eu suspeito que você queria testar se a saída de id -u é maior que 999; isso seria

if (system("id -u " $i "| awk \x27{exit(!($0 > 999))}\x27"))

\x27 é uma maneira de colocar um caractere de aspas simples dentro de uma string awk. Mas isso é muito complicado. Em vez disso, leia a saída de id -u no script awk.

id_command = "id -u " $i;
id_command | getline id;
close(id_command);
if (id > 999) print id;
     else $i pass $i,'@email.com' >> newusers.txt

Acho que você quis escrever uma linha no arquivo. Então você precisa de um comando de impressão. Para colocar um espaço entre os elementos, passe-os como argumentos separados para print . Para unir duas strings sem espaços em branco, coloque as strings próximas umas das outras no script awk sem nenhum operador entre (no awk, o operador binário nulo significa concatenação). E como já vimos várias vezes, use aspas duplas ao redor de strings.

    else print $i, pass, $i "@email.com" >>"newusers.txt"

Pode haver outros problemas com o seu script, eu não o revisei completamente.

    
por 15.03.2017 / 01:30

Tags