Найти минимальное значение в столбце из нескольких файлов и распечатать в другом файле

Найти минимальное значение в столбце из нескольких файлов и распечатать в другом файле

У меня есть файл1, который выглядит так

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 

Мне нужно найти минимальное значение из столбца 1 и вывести его в другом файле_NEW

Теперь мне нужно повторить вышеизложенное для разных файлов и найти минимум для 100 файлов.

Так что у меня будет конечный вывод в file_NEW что-то вроде этого

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

Здесь file2 и file3 имеют похожие наборы данных, как file1. Все входные файлы имеют одинаковые шаблоны имен, например file*.txt, и находятся в одном каталоге.

Может ли кто-нибудь подсказать, как это сделать с помощью awk или sed?

Спасибо

решение1

Чтобы найти минимальное значение, мы можем использовать следующую команду:

Используйте следующую команду для каждого файла

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

Проверено и работает отлично

решение2

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

Вышеуказанное будет работать надежно и эффективно со всеми вашими входными файлами одновременно с использованием стандартных инструментов UNIX, например:

$ 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)

но предполагает, что ни одно из имен ваших файлов не содержит символов табуляции или новой строки. Если они содержат табуляции, то это простая настройка для их обработки:

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

но если они также содержат символы новой строки, то вам понадобятся инструменты GNU для поддержки \0(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]++'

решение3

Версияsed

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при необходимости скопируйте выходной файл и добавьте имена файлов

решение4

IIUC, вам нужно это для каждого файла:

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

Начальная awk 'NF' FILEнужна в случае, если у вас были пустые строки во входных файлах. Вы не указали, хотите ли вы запустить эту команду для всех файлов в указанном каталоге рекурсивно или нерекурсивно или только для некоторых файлов с определенными шаблонами в именах. В любом случае, вы можете использовать findдля этого:

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

В этом случае указанная выше команда выполняется для всех файлов в указанном каталоге, имя которых начинается с FILE.

Также обратите внимание, что это не обязательно даст вам отсортированный список на выходе, file_NEWпоскольку findбудет слепо выполняться все последующее -exec для каждого найденного файла.

Связанный контент