ZSH: 'ls *(.)' перечисляет регулярные файлы только, но 'ls * (/)' не перечисляет каталоги только

Это различие относится ко времени исходного Unix Беркли и происходит от того, что ядро не может на самом деле сохранить прокручивающееся среднее число; это должно было бы сохранить большое количество прошлых чтений, чтобы сделать так, и особенно в былые времена просто не было памятью для экономии для него. Алгоритм, используемый вместо этого, имеет преимущество, которое должно сохранить все ядро, результат предыдущего вычисления.

Следует иметь в виду, что алгоритм был немного ближе к истине назад, когда компьютерные скорости и соответствующие такты измерялись в десятках МГц вместо GHz; существует намного больше времени для несоответствий для сползания в эти дни.

7
01.09.2011, 23:00
3 ответа

Я подозреваю, что проблемой не является zsh globbing, но ls поведение по умолчанию, это при предоставлении список аргументов каталога содержания каталога.

Я предлагаю попробовать

ls -d -- <your-glob-here>

Лучший способ протестировать Ваши шарики с

printf '%s\n' <glob>

или

print -rC1 -- <glob>
14
27.01.2020, 20:15
  • 1
    Другой способ протестировать шарики с zsh состоит в том, чтобы снабдить вкладками - разворачивают их. Это заменит шарик всеми подобранными путями. –  Jonas Schäfer 13.08.2015, 13:36

@enzotib является правильным, и имея это в виду команда, которая перечисляет каталоги под pwd в zsh:

ls .(/)

-1
27.01.2020, 20:15
  • 1
    Нет, ls .(/) перечисляет содержание текущего каталога (каталоги и некаталоги одинаково). С тех пор . всегда каталог, этот шаблон эквивалентен .. –  Gilles 'SO- stop being evil' 02.09.2011, 02:51
  • 2
    Спасибо @Guilles, я думаю, что Вы правы. Я рад оставить свой ответ в случае, если любой делает ту же ошибку. –  Amelio Vazquez-Reina 02.09.2011, 02:57

Еще один способ добиться этого -

 print *(/)

или

 echo *(/)

Update1

Немного дополнительная правильная версия (как отмечено by @ Stéphane Chazelas) будет

print -rl -- *(/) 

или

echo -E - *(/)

, чтобы позаботиться о пробелах (-l), escape-последовательностях (-r / -E) и начальных дефисах (- / -) внутри имен файлов.

Update2

Тем не менее еще правильная версия - print -rN , которая дополнительно заботится о переносах строк внутри имен файлов (Linux позволяет, а Windows нет) путем разделения результатов с нулями, например:

print -rN -- **/*(/) |xargs -0 -n10 chmod g+s

, который рекурсивно устанавливает бит setguid - выборочно обращаясь к каталогам, в отличие от chmod -R g + s .

Update3

Для огромных деревьев это обрабатывает только часть файлов (из-за ограничения на длину командной строки), а остальные автоматически оставляет как есть. Следующие команды могут справиться с этой ситуацией:

find . -type d -print0 |xargs -0 -n10 chmod g+s
1
27.01.2020, 20:15

Теги

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