sintaxis script lista lineas linea leer fichero extraer ejemplos completa comandos comando basicos linux unix command-line

linux - script - ¿Cuál es una forma fácil de leer una línea aleatoria de un archivo en la línea de comandos de Unix?



lista completa de comandos linux pdf (13)

Aquí hay un script de Python simple que hará el trabajo:

import random, sys lines = open(sys.argv[1]).readlines() print(lines[random.randrange(len(lines))])

Uso:

python randline.py file_to_get_random_line_from

¿Cuál es una forma fácil de leer una línea aleatoria de un archivo en la línea de comandos de Unix?


Esto es lo que descubrí, ya que mi Mac OS no usa todas las respuestas fáciles. Utilicé el comando jot para generar un número, ya que las soluciones de la variable $ RANDOM no parecen ser muy aleatorias en mi prueba. Al probar mi solución, tuve una gran variación en las soluciones proporcionadas en la salida.

RANDOM1=`jot -r 1 1 235886` #range of jot ( 1 235886 ) found from earlier wc -w /usr/share/dict/web2 echo $RANDOM1 head -n $RANDOM1 /usr/share/dict/web2 | tail -n 1

El eco de la variable es obtener una visualización del número aleatorio generado.


Esto es simple.

cat file.txt | shuf -n 1

Por supuesto, esto es solo un poco más lento que el "shuf -n 1 file.txt" por sí mismo.


Línea de bash único:

sed -n $((1+$RANDOM%`wc -l test.txt | cut -f 1 -d '' ''`))p test.txt

Problema leve: duplicar nombre de archivo.


Otra alternativa:

head -$((${RANDOM} % `wc -l < file` + 1)) file | tail -1


Otra forma de usar '' awk ''

awk NR==$((${RANDOM} % `wc -l < file.name` + 1)) file.name


Una solución que también funciona en MacOSX, y también debería funcionar en Linux (?):

N=5 awk ''NR==FNR {lineN[$1]; next}(FNR in lineN)'' <(jot -r $N 1 $(wc -l < $file)) $file

Dónde:

  • N es el número de líneas aleatorias que deseas

  • NR==FNR {lineN[$1]; next}(FNR in lineN) file1 file2 NR==FNR {lineN[$1]; next}(FNR in lineN) file1 file2 -> guardar números de línea escritos en file1 y luego imprimir la línea correspondiente en file2

  • jot -r $N 1 $(wc -l < $file) -> dibuja N números al azar ( -r ) en el rango (1, number_of_line_in_file) con jot . La sustitución del proceso <() hará que se vea como un archivo para el intérprete, por lo que file1 en el ejemplo anterior.

Usando solo vainilla sed y awk, y sin usar $ RANDOM, un sencillo "de una sola línea" para ahorrar espacio y razonablemente rápido para seleccionar una sola línea de forma pseudoaleatoria desde un archivo llamado FILENAME es el siguiente:

sed -n $(awk ''END {srand(); r=rand()*NR; if (r<NR) {sub(//..*/,"",r); r++;}; print r}'' FILENAME)p FILENAME

(Esto funciona incluso si FILENAME está vacío, en cuyo caso no se emite ninguna línea).

Una posible ventaja de este enfoque es que solo llama a rand () una vez.

Como lo señaló @AdamKatz en los comentarios, otra posibilidad sería llamar a rand () para cada línea:

awk ''rand() * NR < 1 { line = $0 } END { print line }'' FILENAME

(Se puede dar una prueba simple de corrección basada en la inducción).

Advertencia sobre rand()

"En la mayoría de las implementaciones de awk, incluyendo gawk, rand () comienza a generar números desde el mismo número de inicio, o semilla, cada vez que ejecutas awk".

- https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html


utilizando un script bash:

#!/bin/bash # replace with file to read FILE=tmp.txt # count number of lines NUM=$(wc - l < ${FILE}) # generate random number in range 0-NUM let X=${RANDOM} % ${NUM} + 1 # extract X-th line sed -n ${X}p ${FILE}


perlfaq5: ¿Cómo selecciono una línea aleatoria de un archivo? Aquí hay un algoritmo de muestreo de yacimiento del Libro de camellos:

$ perl -e ''srand; rand($.) < 1 && ($line = $_) while <>; print $line;'' file

Esto tiene una ventaja significativa en el espacio sobre la lectura de todo el archivo. Puede encontrar una prueba de este método en El arte de la programación de computadoras, Volumen 2, Sección 3.4.2, por Donald E. Knuth.


Puedes usar shuf :

shuf -n 1 $FILE

También hay una utilidad llamada rl . En Debian, está en el paquete de randomize-lines que hace exactamente lo que usted quiere, aunque no está disponible en todas las distribuciones. En su página de inicio, en realidad recomienda el uso de shuf (que no existía cuando se creó, creo). shuf es parte de los coreutils de GNU, rl no lo es.

rl -c 1 $FILE


#!/bin/bash IFS=$''/n'' wordsArray=($(<$1)) numWords=${#wordsArray[@]} sizeOfNumWords=${#numWords} while [ True ] do for ((i=0; i<$sizeOfNumWords; i++)) do let ranNumArray[$i]=$(( ( $RANDOM % 10 ) + 1 ))-1 ranNumStr="$ranNumStr${ranNumArray[$i]}" done if [ $ranNumStr -le $numWords ] then break fi ranNumStr="" done noLeadZeroStr=$((10#$ranNumStr)) echo ${wordsArray[$noLeadZeroStr]}


sort --random-sort $FILE | head -n 1

(Aunque me gusta el enfoque de Shuf, incluso mejor. Ni siquiera sabía que existía y nunca hubiera encontrado esa herramienta por mi cuenta)