Como posso adicionar uma string aleatória para cada linha?

11

Estou tentando adicionar uma sequência aleatória para cada linha durante a execução:

awk '{print "name" "'$ran'" "-"$0}' 'myfile'

Antes disso, a string aleatória é gerada:

ran="$(tr -dc '[:alnum:]' </dev/urandom | head -c 6)"

O problema é que ele imprime a mesma string aleatória para cada linha:

nameGQz3Ek-
nameGQz3Ek-
nameGQz3Ek-

O que devo fazer para obter uma string aleatória diferente para cada linha?

    
por user134969 07.03.2018 / 13:29

6 respostas

8

Com a função awk system() :

Amostra input.txt :

a
b
c
awk '{ 
         printf "name";
         system("tr -dc 7[:alnum:]7 </dev/urandom | head -c6");
         printf "-%s\n", $0
     }' input.txt

Exemplo de saída:

nameSDbQ7T-a
nameAliHY0-b
nameDUGP2S-c

system(command)
Execute the operating system command command and then return to the awk program

link

    
por 07.03.2018 / 13:47
8

Você não acha óbvio? Você está apenas gerando uma string aleatória uma vez e armazenando-a na variável ran e usando-a para todas as linhas!

Usando getline em uma variável de um pipe

awk '{
     str_generator = "tr -dc '[:alnum:]' </dev/urandom | head -c 6"
     str_generator | getline random_str
     close(str_generator)
     print "name " random_str " - " $0
}' file

Quando você usa command | getline var , a saída do comando é enviada por meio de um canal para getline() e para a variável var .

Observe também que quando um canal é aberto para saída, awk lembra o comando associado a ele e as gravações subsequentes no comando são anexadas às gravações anteriores. Precisamos fazer uma chamada close() explícita do comando para evitar isso.

Se as aspas simples aninhadas no str_generator estiverem causando problemas, substitua pelo seu equivalente octal ( 7 )

awk '{
     str_generator = "tr -dc 7[:alnum:]7 </dev/urandom | head -c 6"
     str_generator | getline random_str
     close(str_generator)
     print "name " random_str " - " $0
}' file
    
por 07.03.2018 / 13:41
8

A execução de uma instância de tr -dc '[:alnum:]' </dev/urandom | head -c 6 por linha de entrada seria contraproducente. Seria melhor fazer isso:

<input awk -v rng="LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | fold -w 6" '
  {rng | getline r; print "name"r"-"$0}'

Se sua entrada não contiver backticks nem aspas simples, você também poderá usar m4 ' mkstemp() :

<input sed "s/.*/mkstemp(name)\'&'/" | m4
    
por 07.03.2018 / 15:03
4

Esta variação em algumas das outras respostas faz a geração aleatória de strings fora de awk :

LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | fold -w 6 |
awk '{ getline r <"/dev/stdin"; printf("name%s-%s\n", r, $0) }' file

O fluxo tr + fold gera um fluxo interminável de sequências aleatórias de seis caracteres na entrada padrão de awk . awk ignorará a entrada padrão se um nome de arquivo for fornecido, portanto, essas sequências aleatórias são lidas por getline de /dev/stdin na variável r . printf é então usado para prefixar as linhas do arquivo com a string apropriada.

Dado o arquivo

123
abc
@#$

isso pode produzir

nameFI4L1S-123
name5S8Shr-abc
namebRUjzV-@#$
    
por 07.03.2018 / 15:08
1

Sem usar o awk, apenas bash

while read line; do
    printf "name%s-%s\n" \
        "$(tr -dc '[:alnum:]' </dev/urandom|head -c6)" \
        "$line"
done <myfile
    
por 08.03.2018 / 19:18
0
paste <(base64 -w6 /dev/urandom) input.txt | awk 'NF==2{print $1$2} NF!=2{exit}'

Requisitos - o input.txt deve conter apenas uma coluna, em outras palavras, não deve ter guias ou espaços, porque eles são usados como separador padrão por awk e paste ( apenas o caractere de tabulação). Caso contrário, o comando deve ser modificado um pouco.

Nota: O alfabeto Base64 contém + e / caracteres: tabela Base64 , se Se você quiser apenas números e letras, use o comando base32 - Alfabeto Base32 .

Entrada

===my_line_a
===my_line_b
===my_line_c
===my_line_d
===my_line_e

=== caracteres adicionados para maior clareza.

Resultado

LYSdm8===my_line_a
5sSSNt===my_line_b
YVMdkA===my_line_c
3b/nsT===my_line_d
xt/AZO===my_line_e
    
por 08.03.2018 / 18:15

Tags