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

Обычный, когда я хочу показать название первого файла из каталога, я ввожу:

ls raw/all | head -n 1

Но это занимает много времени когда в каталоге там любые много файлов


Например, для dir с близко к файлам на 900 К у нас есть следующие измерения:

time ls raw/all | head -n 1 

real    0m17.250s | 0m10.328s | 0m6.334s
user    0m3.224s  | 0m3.884s  | 0m3.192s
sys     0m0.544s  | 0m0.664s  | 0m0.572s

цикл с условием продолжения по всем файлам берет:

time ls raw/all | wc -l

real    0m6.455s | 0m5.869s  | 0m5.228s
user    0m3.612s | 0m3.468s  | 0m4.072s
sys     0m0.460s | 0m0.784s  | 0m0.624s

Как расшифровка подписи первого файла эффективным способом?

1
задан 16 August 2017 в 18:08

1 ответ

Это хитро. Два подхода:


Подход 1; find:

find . -mindepth 1 -print -quit

find и -prints первый файл, найденный, и -quits сразу. -mindepth 1 предотвратил бы соответствие . hardlink текущего каталога.

Если Вы интересуетесь регулярными файлами только, добавить -type f:

find . -type f  -print -quit

-mindepth 1 может быть отброшен затем как . быть каталогом не было бы подобрано.


Подход 2; sh, stdbuf, и awk:

Обратите внимание, что, это могло бы пострадать от ARG_MAX будучи инициированным для слишком многих файлов (список аргументов, становящийся слишком длинным, ARG_MAX байты). В этом случае используйте подход 1.

  • любая оболочка builin (например. printf, echo) распечатать имя файла
  • окружите globbing, *, сделать расширение (порядок сопоставления должен совпасть с ls для данного locale LC_COLLATE)
  • stdbuf -o0 (stdbuf идет с GNU coreutils) сделать поток STDOUT printf/echo освободивший буфер
  • канал (|) STDOUT printf/echo кому: awk и exit после печати первой записи
  • После awk выходы, stdbuf (printf) получил бы SIGPIPE, и был бы уничтожен
  • Я использовал бы printf разделить имена файлов ASCII NUL (\0), и использование \0 как разделитель записей в awk для занятия любыми пограничными случаями до, имена файлов затронуты

Соединение их:

stdbuf -o0 printf '%s\0' * | awk 'BEGIN{RS="\0"} {print;  exit}'
2
ответ дан 7 December 2019 в 13:30

Другие вопросы по тегам:

Похожие вопросы: