У меня есть тонна файлов в подпапках, каждая из которых содержит три столбца чисел. Мне нужно найти наибольшее число в 2 доллара, а затем вывести столбцы 1 и 2 доллара.
Вот что у меня получилось:
awk 'FNR > 1 {max=dist=0; if ($2>max){dist=$1; max=$2}}END{print FILENAME " distance: " dist " max: " max}' ./nVT_*K/rdf_rdf_aam_aam_COM.dat
Это работает, однако выводит значения только для последнего входного файла. Мне нужно по одному от каждого.
Итерация с использованием цикла bash for привела к появлению сообщения «команда не найдена» для части awk. В настоящее время я отправляю вывод echoed for loop в файл и выполняю его как сценарий, хотя в долгосрочной перспективе это невыполнимый план.
Может ли кто-нибудь помочь разбросать это, чтобы он мог взять кучу входных файлов в разных подпапках и распечатать предполагаемый результат из каждого файла как такового:
./nVT_277K/rdf_rdf_aam_aam_COM.dat distance: 4.650000 max: 1.949975
./nVT_283K/rdf_rdf_aam_aam_COM.dat distance: 4.650000 max: 1.943047
./nVT_289K/rdf_rdf_aam_aam_COM.dat distance: 4.650000 max: 1.907280
...
...
...
Я был бы чрезвычайно благодарен за любой вклад здесь. Спасибо
С GNU awk для ENDFILE:
awk '
FNR > 1 { if ((max= = "") || ($2>max)) {dist=$1; max=$2} }
ENDFILE { print FILENAME " distance: " dist " max: " max; max=dist = "" }
' ./nVT_*K/rdf_rdf_aam_aam_COM.dat
С любым awk и при условии, что ваши входные файлы не пусты:
awk '
FNR==1 { if (NR>1) print fname " distance: " dist " max: " max; max=dist = ""; fname=FILENAME; next }
(max= = "") || ($2>max) {dist=$1; max=$2} }
END { print fname " distance: " dist " max: " max }
' ./nVT_*K/rdf_rdf_aam_aam_COM.dat
Этот первый сценарий на самом деле не будет работать на Mac, если на этом Mac не запущена GNU awk. Он не будет работать на OSX / BSD awk, потому что ENDFILE
является расширением GNU awk, а не частью спецификации POSIX. Я добавил версию, которая будет работать на любой awk.
Что ж, я тоже не ожидал, что он запустится (раньше у меня были проблемы с END / ENDFILE), хотя, к моему удивлению, выполнение команды с помощью «awk» или «gawk» дает те же результаты без ошибок, о которых сообщалось.
Вы не получите отчета об ошибке, поскольку ENDFILE
для любого не-gawk - это просто неинициализированная переменная и поэтому имеет значение ноль или ноль, которое оценивается как ложное условие в контексте в моем первом скрипте, и поэтому оно не будет генерировать никаких выход. Вы можете заменить ENDFILE на AARDVARK и получить тот же результат с awk, отличным от GNU.
Знаете что, я не могу сказать вам, почему и как, хотя это действительно работает, и я один счастливый awk n00b. У вас есть фантастические выходные и еще одно огромное спасибо за то, что сэкономили мне несколько часов работы
предполагая, что есть хотя бы одно положительное значение (так что нам не нужно инициализировать)
$ awk 'FNR==1 {f=FILENAME}
$2>max[f] {max[f]=$2; dist[f]=$1}
END {for(f in max) print f, "distance:", dist[f], "max:", max[f]}' files
max и distance индексируются по именам файлов, поскольку должны быть уникальными в пределах заданного пути ...
Спасибо! Ближе, хотя и неправильно, это выполняет итерацию всех входных файлов, и результат выглядит так, как задумано, однако функция, похоже, оценивает неправильное значение, по-видимому, значение «dist» ($ 1) вместо «max» $ 2. Это результат: ./nVT_331K/rdf_rdf_aam_aam_COM.dat distance: 14.950000 max: 0.983862 ./nVT_325K/rdf_rdf_aam_aam_COM.dat distance: 14.950000 max: 0.983969 ./nVT_319K/rdf_rdf_aam_aam_COM.dat distance: 14.950000 max: 0.982654
14.950000 - последнее и самое большое число из 1 доллара (0,000000-14,950000), мне нужен 1 доллар, когда 2 доллара - "максимум".
Спасибо, Эд, это было именно то, что мне было нужно, и оно одинаково хорошо работает как с версией awk для Mac, так и с GNU. Я проанализирую код и выясню, где я ошибся. Возможно, вчера в офисе была температура 34 ° C, что затруднило логическое мышление.