Как правило, вы должны использовать find
для рекурсивного поиска в каталогах, т.е.
find. -name '*.cpp'
Если у вас GNU find
, вы можете напрямую распечатать имя файла и размер в байтах, минуя вызовstat
find. -name '*.cpp' -printf '%f:%s\n'
Если вы не возражаете против обратного порядка, вы можете вывести результаты таким образом, чтобы их можно было однозначно сортировать -, например, сортировать по размеру в числовом порядке от большего к меньшему
find../src -name '*.cpp' -printf '%s:%f\n' | sort -t: -rn
Вы всегда можете поменять местами поля после сортировки, например. с Awk -, который также позволяет вам выбрать, например, только 5 лучших результатов:
find. -name '*.cpp' -printf '%s:%f\n' | sort -t: -rn | awk -F: 'NR==6 {exit} {print $2 " : " $1}'
Наконец, если вы хотите сделать его безопасным для любых «легальных» имен файлов (, в том числе с символами новой строки ), нуль завершает все
find. -name '*.cpp' -printf '%s:%f\0' | sort -t: -zrn | awk -vRS='\0' -F: 'NR==6 {exit} {print $2 " : " $1}'
read
также является встроенной -оболочкой, о которой which
не знает. Попробуйте запустить:
$ type read
read is a shell builtin
Что касается того, почему /usr/bin/read
не работает, я не уверен, что это за приложение, поскольку оно не установлено в моей системе, но, скорее всего, вам нужна встроенная оболочка -..
read
— это встроенная оболочка, т. е. команда, предоставляемая самой оболочкой, а не внешней программой. Дополнительные сведения о встроенных командах оболочки см. в . В чем разница между встроенной командой и другой?
read
должен быть встроенным, потому что он изменяет состояние оболочки, в частности, устанавливает переменные, содержащие вывод. Внешняя команда не может установить переменные вызывающей их оболочки. См. также Почему cd не является программой? .
Некоторые системы также имеют внешнюю команду, называемую read
, по спорным причинам соответствия . Внешняя команда не может выполнять всю работу команды :, она может читать строку ввода, но она не может устанавливать переменные оболочки в то значение, которое она читает, поэтому внешнюю команду можно использовать только для отбрасывания строки ввода. ввод, а не для его обработки.
which read
не говорит вам, что встроенная функция существует, потому что это не ее работа. which
сама по себе является внешней командой в bash и других оболочках в стиле Bourne -(, за исключением zsh ), поэтому она сообщает только информацию о внешних командах. Очень редко бывает веская причина для коллаwhich
. Команда, чтобы узнать, что означает имя команды,type
.
bash-5.0$ type read
read is a shell builtin
read
— это встроенная оболочка, влияющая на текущую среду. /usr/bin/read
— это внешняя команда, которая выполняется в подоболочке и поэтому не может.
Так зачем же нам вообще /usr/bin/read
, если он практически бесполезен? Ответ: POSIX. Это требует, чтобы встроенные команды также существовали как внешние команды!
Так, например, есть еще команда /usr/bin/cd
. Давайте пройдемся по этому... он создает вложенную оболочку, запускает скрипт (, который в основном builtin cd "$@"
), а затем завершает работу... так что он не делает ничего полезного.
Обоснование этой странности описано здесь:https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap01.html#tag_23_01_07
why Example 1 below works and Example 2 does not?
Потому что выполняемая команда read
отличается.
Таким образом, каждый действует по-своему.
Мы можем настроить внешний исполняемый файл для явного отображения разницы:
sudo mv /usr/bin/read /usr/bin/read.back # keep a backup
echo $'#/bin/bash\necho "This is an external $0"' | sudo tee /usr/bin/read
sudo chmod a+x /usr/bin/read
С измененным исполняемым файлом это все еще работает:
read a b c <<<'one two three'
echo "$a $b $c"
Но это (очевидно )не:
/usr/bin/read a b c <<<'111 222 333'
echo "$a $b $c"
Причина в том, что в bash (и в большинстве оболочек POSIX )есть порядок поиска команд. Первая найденная команда и будет выполнена. Этот порядок может быть показан type -a
в bash:
$ type -a read
read is a shell builtin
read is /usr/bin/read
read is /bin/read
Это объясняет, почему встроенная функция выполняется даже при наличии внешних исполняемых файлов с таким же эффективным именем.
Причина, по которой Redhat предоставляет внешний /usr/bin/read
, немного сложнее и на самом деле связана с тем, как работает POSIX.
Как упоминалось другими, «чтение» — это встроенная -оболочка. В моей системе нет /usr/bin/read. Однако man read
сообщает мне:
NAME read - read from a file descriptor
SYNOPSIS #include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
DESCRIPTION read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
Таким образом, такое чтение является системным вызовом и инструментом программирования.
ОДНАКО! Не используйте чтение вообще. У вас есть «данные», и вам нужен массив.
IFS=',';my_array=( ${data[@]} )
for item in "${my_array[@]}"; do echo "$item"; done
pig
cow
horse
rattlesnake