Ваша проблема возникла из-за того, что только после чтения всех входных файлов awk достигает предложения END .
Замена первой строки вашего цикла for
следующей должна решить вашу проблему.
RESULT=$(awk 'BEGIN{curr_f=FILENAME; nr=1} {if(curr_f!=FILENAME){if(mean > max_mean){max_mean=mean; f=curr_f} curr_f=FILENAME; nr=0; sum=0} } { sum+=$4; nr++; mean=sum/nr } END{if(mean>max_mean){print mean, FILENAME}else{print max_mean, f}}' ${x}[1-4]/${x}[1-4].txt )
Это будет длинный ответ, а не ответ типа да -или -нет. В нем описываются различные аспекты программирования, охватываемые функциями Bash, которые следует учитывать при выборе направления действия.
В конце вы можете найти демонстрацию определения одной функции в отдельном, но параметризованном исходном файле.
Функция:
Принимая во внимание вышеизложенное, для чего он нужен и есть ли у него альтернативы?
Логическая организация кода
Группировка пакета команд, предназначенных для определенной цели, имеет большой смысл. Ведь это одно из значений термина функция-что-то имеет такую-то функцию .Однако та же цель может быть достигнута и другими способами:
{... }
. (... )
подоболочки. 1Пакетные операции
Функции позволяют легко перенаправлять массовые операции ввода-вывода с помощью стандартных операторов Bash. Блоки, подоболочки, выполнение скриптов и источники тоже работают, но для чисто визуальных групп команд изменения дескриптора файла ввода-вывода должны применяться с помощью exec
.
Локализация
Это одна из вещей, которая делает функции особенными по сравнению с простыми блоками. Возможность создавать переменные local
. И это часто является хорошей практикой программирования, поскольку она сохраняет видимость переменных на самом низком уровне, что уменьшает беспорядок в более широком пространстве имен и вводит изоляцию. Что, в свою очередь, является ценным элементом безопасности.
В качестве альтернативы здесь можно использовать отдельные сценарии и подоболочки. Исходные файлы тоже, что касается позиционных параметров.
Параметризация
Каждая функция получает собственный набор позиционных параметров $1
, $2
и т. д. Это позволяет явно изменять поведение функций при вызове команды.
Альтернативы здесь включают автономные -сценарии и исходные файлы.
Код идентификация
Имя функции уникально, и это означает не только их однозначное распознавание,но и возможность их выполнения. И много раз нужно. Ни блоки {}
, ни подоболочка, ни группировка простого текста не предлагают этого -, если они не охватываются циклами. Хотя скрипты и исходные файлы делают.
Информация
Наконец, как имя функции, так и любые комментарии, которые оно может содержать, учитывают понятность кода. Все остальные варианты дают здесь свободу действий, но анонимные решения, такие как подоболочка и блок {}
, не могут облегчить формальное название (и адрес )для блока кода.
Вот пример разумного размещения одной функции в отдельном исходном файле.
case "$1" in
a)
f () { echo "This function was defined in a)."; }
;;
b)
f () { echo "This function was defined in b)."; }
;;
*)
f () { echo "This function was defined with no recognised argument."; }
;;
esac
Это условное определение действует как фабрика функций. Файл, полученный из другого источника, устанавливает туда функцию f
. Весь этот код может быть включен в другую функцию, и в его нынешнем виде разница будет невелика. Но как только генератор функций становится достаточно большим, чтобы стать самостоятельным объектом, этот подход объединяет лучшее из двух :функцию и исходный файл.
См. также
На самом деле Bash допускает аналогичное определение функции :f () (...;)
. Определенная таким образом функция f
будет выполняться в собственной подоболочке.
Я делаю и то, и другое в зависимости от обстоятельств. В большинстве случаев я буду объявлять функции в том же скрипте, который будет их использовать, однако у меня есть «инструментарий» скриптов, в котором есть файл переменных и функций, которые будут общими для всех скриптов.
Функционировать или не функционировать
Основная цель функции — СУХОЙ (Не повторяйтесь ). Если у вас есть код, который будет использоваться в вашем скрипте более одного раза, он должен быть в функции.
Использование функций для неповторяющегося кода -является вопросом предпочтения. Некоторые люди (, в том числе и я ), считают, что это более аккуратно. Кроме того, я думаю, что это больше похоже на то, как используются «настоящие» языки программирования.
В Руководстве по стилю оболочки Google говорится, что если ваш код содержит хотя бы одну функцию, вы должны использовать "основную" функцию в качестве оболочки для всего вашего кода. (По сути, ваш скрипт будет состоять только из серии объявлений функций, заканчивающихся одним вызовомmain
)
Объявление функций (или написание кода )внутри одного скрипта
Если вы пишете автономный сценарий для выполнения одной задачи, возможно, вам подойдет этот способ.
Объявление функций внутри отдельного файла
Если вы создаете набор инструментов с множеством общих функций, скорее всего, вам подойдет этот способ.
В моем примере есть функции, которые используются всеми или, по крайней мере, большинством скриптов в наборе инструментов. Это включает в себя некоторые функции, которые запрашивают нашу систему управления запасами и возвращают информацию о серверах, такую как IP-адрес,версия ОС и т. д. Эта информация полезна для многих инструментов, поэтому имеет смысл объявлять такие функции в одном файле, а не во всех файлах по отдельности. Кроме того, мы недавно внесли изменения в систему управления запасами, поэтому вместо изменения более 10 разных файлов мне нужно было изменить только общий файл для запроса новой системы, остальные файлы по-прежнему работают правильно без изменений.
Некоторыми недостатками этого метода является его сложность. Каждый файл имеет следующий оператор для источника этого общего файла:
if [[ -f "${0%/*}/lib/common.sh" ]]; then
. "${0%/*}/lib/common.sh"
else
echo "Error! lib/common.sh not found!"
exit 1
fi
Если пользователи захватят набор инструментов и изменят структуру каталогов или не захватят всю структуру каталогов, инструменты не будут работать должным образом, поскольку они не смогут получить общий файл.