¿Cómo puedo agregar una cadena aleatoria para cada línea?


12

Estoy tratando de agregar una cadena aleatoria para cada línea mientras se ejecuta:

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

Antes de eso, se genera la cadena aleatoria:

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

El problema es que imprimirá la misma cadena aleatoria para cada línea:

nameGQz3Ek-
nameGQz3Ek-
nameGQz3Ek-

¿Qué debo hacer para obtener diferentes cadenas aleatorias para cada línea?


En lugar de alguna variación de tr -dc '[:alnum:]' </dev/urandom | head -c 6, sería más simple y computacionalmente más eficiente de usar pwgen -s 6 1, o mejor aún, pwgen -s 6 $(wc -l myfile)le dará exactamente todas las cadenas aleatorias que necesita, de una sola vez.
user1404316

Respuestas:


9

Con función awk system() :

Muestra input.txt:

a
b
c

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

Salida de muestra:

nameSDbQ7T-a
nameAliHY0-b
nameDUGP2S-c

system(command)
Ejecute el comando del sistema operativo commandy luego regrese al programa awk

https://www.gnu.org/software/gawk/manual/gawk.html#index-system_0028_0029-function


Bien, pero ¿por qué me estoy poniendo tr: write error: Broken pipe?
user134969

@ user134969, funciona bien. Asegúrese de no haber cometido ningún error en la línea de comando
RomanPerekhrest

9

¿No crees que es un poco obvio? ¡Solo está generando una cadena aleatoria una vez y la almacena en ranvariable y la usa para todas las líneas!

Utilizando getlineen una variable de una tubería

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

Cuando lo usa command | getline var, la salida del comando se envía a través de una tubería hacia getline()y dentro de la variable var.

También tenga en cuenta que cuando se abre una tubería para salida, awkrecuerda el comando asociado con él y las escrituras posteriores al comando se agregan a las escrituras anteriores. Necesitamos hacer una close()llamada explícita del comando para evitar eso.

Si las comillas simples anidadas en el str_generatorestán causando un problema, reemplace con su equivalente octal ( \047)

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

8

Ejecutar una instancia de tr -dc '[:alnum:]' </dev/urandom | head -c 6por línea de entrada sería contraproducente, sería mejor hacerlo:

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

Si su entrada no contiene backticks ni comillas simples, también puede usar m4's mkstemp():

<input sed "s/.*/mkstemp(name)\`&'/" | m4

4

Esta variación en un par de las otras respuestas hace la generación de cadenas aleatorias fuera 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

La canalización tr+ foldgenera un flujo interminable de cadenas aleatorias de seis caracteres en la entrada estándar de awk. awkignorará la entrada estándar si se proporciona un nombre de archivo, por lo que estas cadenas aleatorias se leen getlinedesde /dev/stdindentro de la variable r. printfluego se usa para prefijar las líneas del archivo con la cadena apropiada.

Dado el archivo

123
abc
@#$

esto puede producir

nameFI4L1S-123
name5S8Shr-abc
namebRUjzV-@#$


0
paste <(base64 -w6 /dev/urandom) input.txt | awk 'NF==2{print $1$2} NF!=2{exit}'

Requisitos : el input.txt debe contener solo una columna, en otras palabras, no debe tener tabulaciones o espacios, ya que se utilizan como separador predeterminado por awky paste(solo caracteres de tabulación) comandos. De lo contrario, el comando debe modificarse un poco.

Nota: El alfabeto Base64 contiene +y /caracteres: tabla Base64 , si solo desea números y letras, puede usar el base32comando - Alfabeto Base32 .

Entrada

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

=== caracteres añadidos para mayor claridad.

Salida

LYSdm8===my_line_a
5sSSNt===my_line_b
YVMdkA===my_line_c
3b/nsT===my_line_d
xt/AZO===my_line_e
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.