Encuentre el valor mínimo en una columna de muchos archivos e imprímalo en otro archivo

Encuentre el valor mínimo en una columna de muchos archivos e imprímalo en otro archivo

Tengo un archivo1 que se parece a este

25       104.601  0.5 
24.8488  104      0.5 
24.5341  103      0.5 
24.1844  102      0.5 
24.1568  101      0.5 
24.1568  100      0.5 
24.1844  99       0.5 
24.5341  98       0.5 

Necesito encontrar el valor mínimo de la columna 1 e imprimirlo en otro archivo_NUEVO

Ahora necesito repetir lo anterior para diferentes archivos y encontrar el mínimo para al menos 100 archivos.

Para tener un resultado final en file_NEW algo como esto

24.1568
23.3254 (from file2)
22.312  (from file3)
.....

Aquí, archivo2 y archivo3 tienen conjuntos de datos similares a los de archivo1. Todos los archivos de entrada tienen los mismos patrones de nombres, como archivo*.txt, y están en el mismo directorio.

¿Alguien puede sugerir cómo hacer esto con awk o sed?

Gracias

Respuesta1

Para encontrar el valor mínimo podemos usar el siguiente comando

Utilice el siguiente comando en cada archivo

awk 'NR==1{sum=$1}($1 < sum){sum=$1}END{print sum}'  filename >> outputfile

Probado y funcionó bien

Respuesta2

awk '{print $1 "\t(from " FILENAME ")"}' file* | sort -k1,1n | awk -F'\t' '!seen[$2]++'

Lo anterior funcionará de manera sólida y eficiente en todos sus archivos de entrada a la vez utilizando herramientas estándar de UNIX, por ejemplo:

$ cat file1
25       104.601  0.5
24.8488  104      0.5
24.5341  103      0.5
24.1844  102      0.5
24.1568  101      0.5
24.1568  100      0.5
24.1844  99       0.5
24.5341  98       0.5

$ cat file2
75       104.601  0.5
74.8488  104      0.5
74.5341  103      0.5
74.1844  102      0.5
74.1568  101      0.5
74.1568  100      0.5
74.1844  99       0.5
74.5341  98       0.5

$ awk '{print $1 "\t(from " FILENAME ")"}' file{1,2} | sort -k1,1n | awk -F'\t' '!seen[$2]++'
24.1568 (from file1)
74.1568 (from file2)

pero asume que ninguno de los nombres de sus archivos contiene tabulaciones o caracteres de nueva línea. Si contienen pestañas, es un simple ajuste manejarlas:

awk '{print $1 "\t(from " FILENAME ")"}' file* |
sort -k1,1n |
awk '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'

pero si también contienen nuevas líneas, entonces necesitarás herramientas GNU para acomodar \0terminadores (NUL):

awk -v ORS='\0' '{print $1 "\t(from " FILENAME ")"}' file* |
sort -z -k1,1n |
awk -v RS='\0' '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'

Respuesta3

una sedversión

find . -name "file*" -exec sh -c '
   echo $(sort -nk1 "$1"  | sed -n "1{s/ .*//p}" )" (from "${1##*/}")" ' sh {} \; | sort -nk1 > output.txt; cat output.txt

sortIngresar el archivo de salida si es necesario y agregar los nombres de los archivos.

Respuesta4

IIUC, quieres esto en cada archivo:

awk 'NF' FILE | sort -n -k1 - | awk 'NR==1{print $1}' >> file_NEW

La inicial awk 'NF' FILEes necesaria en caso de que haya líneas en blanco vacías en los archivos de entrada. No especificó si desea ejecutar este comando en todos los archivos de un directorio determinado de forma recursiva o no recursiva o solo en algunos archivos con patrones específicos en sus nombres. De todos modos, puedes usar findpara hacer eso:

find . -name "FILE*" -exec sh -c 'awk "NF" FILE | sort -n -k1 - | awk "NR==1{print \$1}" >> file_NEW' sh {} \;

En este caso, el comando anterior se ejecuta en todos los archivos del directorio dado cuyo nombre comienza con FILE.

También tenga en cuenta que esto no necesariamente le dará una lista ordenada en la salida file_NEWporque findejecutará ciegamente todo -exec en cada archivo que encuentre.

información relacionada