Come posso aggiungere una stringa casuale per ogni riga?


12

Sto cercando di aggiungere una stringa casuale per ogni riga durante l'esecuzione:

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

Prima di ciò, viene generata la stringa casuale:

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

Il problema è che stamperà la stessa stringa casuale per ogni riga:

nameGQz3Ek-
nameGQz3Ek-
nameGQz3Ek-

Cosa devo fare per ottenere una stringa casuale diversa per ogni riga?


Invece di alcune variazioni di tr -dc '[:alnum:]' </dev/urandom | head -c 6, sarebbe più semplice e più efficiente dal punto di vista computazionale da usare pwgen -s 6 1, o meglio ancora pwgen -s 6 $(wc -l myfile)ti darebbe esattamente tutte le stringhe casuali di cui hai bisogno, in un colpo solo.
user1404316

Risposte:


9

Con la funzione awk system() :

Campione input.txt:

a
b
c

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

Uscita campione:

nameSDbQ7T-a
nameAliHY0-b
nameDUGP2S-c

system(command)
Eseguire il comando del sistema operativo commande quindi tornare al programma awk

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


Bello, ma perché sto ricevendo tr: write error: Broken pipe?
user134969

@ user134969, funziona benissimo. Assicurati di non aver commesso errori dalla riga di comando
RomanPerekhrest

9

Non pensi che sia un po 'ovvio? Stai solo generando una stringa casuale una volta e la memorizzi in una ranvariabile e la usi per tutte le linee!

Usando getlinein una variabile da una 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 si utilizza command | getline var, l'output del comando viene inviato attraverso una pipe ae getline()nella variabile var.

Notare anche quando una pipe viene aperta per l'output, awkricorda il comando associato ad essa e le scritture successive al comando vengono aggiunte alle scritture precedenti. Dobbiamo effettuare una close()chiamata esplicita del comando per impedirlo.

Se le virgolette singole nidificate in str_generatorstanno causando un problema, sostituiscile con il suo equivalente ottale ( \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

Eseguire un'istanza di tr -dc '[:alnum:]' </dev/urandom | head -c 6per riga di input sarebbe controproducente, sarebbe meglio fare:

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

Se il vostro input non contiene né backticks virgolette singole, si potrebbe anche usare m4's mkstemp():

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

4

Questa variazione su un paio di altre risposte genera la generazione di stringhe casuali al di fuori di 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 pipeline tr+ foldgenera un flusso infinito di stringhe casuali di sei caratteri sull'input standard di awk. awkignorerà lo standard input se viene fornito un nome di file, quindi queste stringhe casuali vengono letti dal getlinedal /dev/stdinnella variabile r. printfviene quindi utilizzato per aggiungere un prefisso alle righe dal file con la stringa appropriata.

Dato il file

123
abc
@#$

questo può produrre

nameFI4L1S-123
name5S8Shr-abc
namebRUjzV-@#$


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

Requisiti : input.txt dovrebbe contenere solo una colonna, in altre parole, non dovrebbe avere schede o spazi, poiché sono stati utilizzati come separatore predefinito dai comandi awke paste(solo carattere di tabulazione). Altrimenti, il comando deve essere leggermente modificato.

Nota: l' alfabeto Base64 contiene +e /caratteri: tabella Base64 , se si desidera solo numeri e lettere, è possibile utilizzare il base32comando - Alfabeto Base32 .

Ingresso

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

=== caratteri aggiunti per chiarezza.

Produzione

LYSdm8===my_line_a
5sSSNt===my_line_b
YVMdkA===my_line_c
3b/nsT===my_line_d
xt/AZO===my_line_e
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.