Использование восьмеричных кодов имеет два преимущества, о которых я могу думать, ни один из которых не настолько огромен:
chmod
в Perl или C.Иногда действительно простые утилиты не будут обрабатывать "дружественные" версии; особенно в пространствах пользователя не-GNU.
Далее, некоторые утилиты, выложенные восьмеричный. Например, если Вы работаете umask
для наблюдения, каков текущий umask он выложит его в восьмеричном (хотя в ударе, umask -S
делает символьный).
Так, короче говоря, я сказал бы, что единственная причина предпочесть их состоит в том, чтобы ввести меньше символов, но что, даже если Вы выбираете не использовать их, необходимо знать, как они отображаются так, чтобы можно было выяснить восьмеричный код при столкновении с одной из вещей, которая только делает восьмеричный. Но Вы не должны сразу знать это 5 карт к rx
, только необходимо смочь понять это.
Можно сделать это как решение с двумя передачами в awk:
awk 'FNR == NR { n = $2; next } { print $1, $2/n }' infile infile
Если Ваша версия awk поддерживает блок ENDFILE (например, GNU awk 4 +), можно сделать это как это:
awk 'ENDFILE { n = $2 } FNR != NR { print $1, $2/n }' infile infile
Обратите внимание, что более эффективно seek
в конец файла увидели ответ camh в первый раз.
Объяснение
Первый пример работает путем запоминания предыдущего $2
, т.е. это только оценено когда счетчик местной линии (FNR
) равно глобальному счетчику строки (NR
). next
управляйте пропусками к следующей строке, в этом случае она гарантирует, что последний блок только оценен, когда второй аргумент анализируется.
Второй пример имеет подобную логику, но использует в своих интересах блок ENDFILE, который оценен, когда конец входного файла достигнут.
Если Ваш источник данных является файлом, который может быть считан многократно (т.е. это не поток), необходимо сначала использовать tail(1)
для получения данных, Вы хотите от последней строки и передачи это к awk для ее последовательной обработки файла. tail
будет стремиться в конец файла считать последнюю строку, не будучи должен считать все данные перед ним.
awk -v norm=$(tail -n 1 file | cut -d' ' -f2) '{print $1, $2/norm}' file
Это будет большой победой на больших файлах, где целый файл не поместится в кэш-буфер (значение, что это должно было бы быть считано из диска дважды, однажды для каждой передачи), и поможет до меньшей степени, не будучи должен просканировать вход для получения до последней строки. Меньшие файлы не могут показать много различия подходу с двумя передачами.
Вы могли загрузить их в массив и считать его назад:
awk '{x[i++]=$0} END{for (j=i-1; j>=0;) print x[j--] }'
Вы могли сделать это более эффективно, но это отчасти иллюстрирует почему awk
не правильный инструмент для этого. Продолжите использовать tac
где это возможно, GNU tac является обычно самым быстрым из множества инструментов для этого задания.
$ awk --version GNU Awk 3.1.8
. Можно ли, возможно, включить очень маленькое объяснение, как два входных файла обрабатываются и чтоnext
? – Bernhard 19.12.2012, 10:16