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 \0
terminadores (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 sed
versió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
sort
Ingresar 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' FILE
es 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 find
para 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_NEW
porque find
ejecutará ciegamente todo -exec
en cada archivo que encuentre.