separador script print examples comando campos cadena buscar python bash awk

python - script - Recoger líneas de un archivo basado en números de línea en otro archivo



awk unix (3)

Tengo dos archivos: uno contiene las direcciones (números de línea) y el otro, como este:

archivo de dirección:

2 4 6 7 1 3 5

archivo de datos

1.000451451 2.000589214 3.117892278 4.479511994 5.484514874 6.784499874 7.021239396

Quiero aleatorizar el archivo de datos basado en el número de archivos de direcciones, así que obtengo:

2.000589214 4.479511994 6.784499874 7.021239396 1.000451451 3.117892278 5.484514874

Quiero hacerlo en python o en bash, pero aún no encontré ninguna solución.


Con awk :

awk ''NR==FNR {a[NR]=$0; next} {print a[$0]}'' data.txt addr.txt

  • NR==FNR {a[NR]=$0; next} NR==FNR {a[NR]=$0; next} crea una matriz asociativa a con las claves siendo el número de registro (línea) y los valores siendo el registro completo, esto sería aplicable solo para el primer archivo ( NR==FNR ), que es data.txt . next hace awk para ir a la siguiente línea sin procesar el registro más

  • {print a[$0]} imprime el valor de la matriz con las claves como el número de línea (registro) del archivo addr.txt ( addr.txt )

Ejemplo:

% cat addr.txt 2 4 6 7 1 3 5 % cat data.txt 1.000451451 2.000589214 3.117892278 4.479511994 5.484514874 6.784499874 7.021239396 % awk ''NR==FNR {a[NR]=$0; next} {print a[$0]}'' data.txt addr.txt 2.000589214 4.479511994 6.784499874 7.021239396 1.000451451 3.117892278 5.484514874


Puedes hacerlo, también, dentro de Python , como en este ejemplo:

with open("address_file", ''r'') as f1, open("data_file", "r") as f2: data1 = f1.read().splitlines() data2 = f2.read().splitlines() for k in data1: # Handle exceptions if there is any try: print(data2[int(k)-1]) except Exception: pass

Editar: Como se sugirió @heemayl, aquí hay otra solución que usa solo una list :

with open("file1", ''r'') as f1, open("file2", ''r'') as f2: data = f2.read().splitlines() for k in f1.read().splitlines(): print(data[int(k)-1])

Ambos producirán:

2.000589214 4.479511994 6.784499874 7.021239396 1.000451451 3.117892278 5.484514874


Si no te importa sed , podemos usar la sustitución de procesos para lograr esto fácilmente:

sed -nf <(sed ''s/$/p/'' addr.txt) data.txt

  • -n suprime la impresión predeterminada
  • -f hace que los comandos de lectura sed de la sustitución de proceso <(...)
  • <(sed ''s/$/p/'' addr.txt) crea comandos de impresión sed basados ​​en números de línea en addr.txt

Da la salida:

2.000589214 4.479511994 6.784499874 7.021239396 1.000451451 3.117892278 5.484514874