Для восстановления кэша исполняемых команд использовать rehash
или hash -rf
.
Удостоверьтесь, что Вы не сбросили hash_list_all
опция (это вызывает даже меньше доступов к диску, но делает обновление кэша менее часто).
Если Вы не хотите должными быть вводить команду, можно сказать zsh не доверять своему кэшу при завершении, вставив следующую строку Ваш ~/.zshrc
¹:
zstyle ":completion:*:commands" rehash 1
Существует стоимость производительности, но это незначительно на типичном рабочем столе, устанавливающем сегодня. (Это не, если Вы имеете $PATH
на NFS или исчерпавшей ресурсы RAM системе.)
zstyle
сама команда документируется в zshmodule
страница справочника. Значения стилей документируются в zshcompsys
и zshcompwid
страницы справочника, или можно считать источник (здесь, _command_names
функция). Если Вы хотели некоторую читаемую документацию … при нахождении некоторых сообщите мне!
¹ требует zsh≥4.3.3, Chris Johnsen спасибо
Это делает это безопасным и портативным способом. Это не запутается странными именами файлов.
for f in *; do [ -d ./"$f" ] && find ./"$f" -maxdepth 1 -exec echo \; | wc -l && echo $f; done
Обратите внимание, что это распечатает количество файлов сначала, затем имя каталога на отдельной строке. Если Вы хотите сохранить формат OP, то Вам будет нужно дальнейшее форматирование, например.
for f in *; do [ -d ./"$f" ] && find ./"$f" -maxdepth 1 -exec echo \;|wc -l|tr '\n' ' ' && echo $f; done|awk '{print $2"\t"$1}'
Если у Вас есть определенный набор подкаталогов, Вы интересуетесь, можно заменить *
с ними.
Почему это безопасно? (и поэтому достойный сценария)
Имена файлов могут содержать любой символ кроме /
. Существует несколько символов, которые рассматривает особенно или оболочка или командами. Они включают пробелы, новые строки и тире.
Используя for f in *
конструкция является безопасным способом получить каждое имя файла, независимо от того, что она содержит.
После того как у Вас есть имя файла в переменной, все еще необходимо избежать вещей как find $f
. Если $f
содержавший имя файла -test
, find
жаловался бы на опцию, которую Вы просто дали ему. Способ избежать этого при помощи ./
перед именем; этим путем это имеет то же значение, но это больше не запускается с тире.
Новые строки и пробелы являются также проблемой. Если $f
содержавший "привет, приятель" как имя файла, find ./$f
, find ./hello, buddy
. Вы говорите find
смотреть на ./hello,
и buddy
. Если они не будут существовать, то это будет жаловаться, и это никогда не будет заглядывать ./hello, buddy
. Этого легко избежать - кавычки использования вокруг Ваших переменных.
Наконец, имена файлов могут содержать новые строки, так подсчет новых строк в списке имен файлов не будет работать; Вы получите дополнительный счет для каждого имени файла с новой строкой. Для предотвращения этого не считайте новые строки в списке файлов; вместо этого, новые строки количества (или любой другой символ), которые представляют единственный файл. Это то, почему find
команда имеет просто -exec echo \;
и нет -exec echo {} \;
. Я только хочу распечатать единственную новую строку в целях соответствия файлам.
Предположение, что Вы ищете стандартное решение Linux, относительно простой способ достигнуть этого, с find
:
find dir1/ dir2/ -maxdepth 1 -type f | wc -l
Где find
пересекает два указанных подкаталога, к a -maxdepth
из 1, который предотвращает дальнейшую рекурсию и только сообщает о файлах (-type f
) разделенный новыми строками. Результат затем передается по каналу к wc
считать количество тех строк.
find . -maxdepth 1 -type d
вывод?
– ShyBoy
23.10.2011, 09:14
find $dirs ...
или, (b), если они находятся исключительно в одном высокоуровневом каталоге, шарике из того каталога, find */ ...
– jasonwryan
23.10.2011, 10:29
-exec echo
к Вашей команде находки - тот путь это не повторяет имя файла, просто новая строка.
– Shawn J. Goff
23.10.2011, 14:43
“Без рекурсии”, сделайте Вы имеете в виду это если directoryName1
имеют подкаталоги, затем Вы не хотите считать файлы в подкаталогах? Если так, вот способ считать все регулярные файлы в обозначенных каталогах:
count=0
for d in directoryName1 directoryName2; do
for f in "$d"/* "$d"/.[!.]* "$d"/..?*; do
if [ -f "$f" ]; then count=$((count+1)); fi
done
done
Обратите внимание что -f
тест выполняет две функции: это тестирует, является ли запись, подобранная одним из шариков выше, регулярным файлом, и это тестирует, была ли запись соответствием (если один из шариков ничему не соответствует, шаблон остается, как ¹). Если Вы хотите считать все записи в данных каталогах независимо от их типа, замены -f
с -e
.
Ksh имеет способ сделать файлы точки соответствия шаблонов и произвести пустой список в случае, если никакой файл не соответствует шаблону. Таким образом в ksh можно считать регулярные файлы как это:
FIGNORE='.?(.)'
count=0
for x in ~(N)directoryName1/* ~(N)directoryName2/*; do
if [ -f "$x" ]; then ((++count)); fi
done
или все файлы просто как это:
FIGNORE='.?(.)'
files=(~(N)directoryName1/* ~(N)directoryName2/*)
count=${#files}
Bash имеет различные способы сделать это более простым. Считать регулярные файлы:
shopt -s dotglob nullglob
count=0
for x in directoryName1/* directoryName2/*; do
if [ -f "$x" ]; then ((++count)); fi
done
Считать все файлы:
shopt -s dotglob nullglob
files=(directoryName1/* directoryName2/*)
count=${#files}
Как обычно, это еще более просто в zsh. Считать регулярные файлы:
files=({directoryName1,directoryName2}/*(DN.))
count=$#files
Изменение (DN.)
кому: (DN)
считать все файлы.
¹ Примечание, которому каждый шаблон соответствует сам, иначе результаты могли бы быть выключены (например, если Вы считаете файлы, которые запускаются с цифры, Вы не можете просто сделать for x in [0-9]*; do if [ -f "$x" ]; then …
потому что мог бы быть названный файл [0-9]foo
).
На основе сценария количества ответа Shawn и приема Bash для проверки даже имена файлов с новыми строками печатаются в применимой форме на одной строке:
for f in *
do
if [ -d "./$f" ]
then
printf %q "$f"
printf %s ' '
find "$f" -maxdepth 1 -printf x | wc -c
fi
done
printf %q
должен распечатать заключенную в кавычки версию строки, то есть, однострочной строки, которую Вы могли поместить в сценарий Bash, который будет интерпретироваться как литеральная строка включая (потенциально) новые строки и другие специальные символы. Например, посмотрите echo -n $'\tfoo\nbar'
по сравнению с printf %q $'\tfoo\nbar'
.
find
управляйте работами путем простой печати отдельного символа для каждого файла и затем подсчета работ вместо того, чтобы считать строки.
Вот "в лоб" - выход способ получить Ваш результат, с помощью find
, echo
, ls
, wc
, xargs
и awk
.
find . -maxdepth 1 -type d -exec sh -c "echo '{}'; ls -1 '{}' | wc -l" \; | xargs -n 2 | awk '{print $1" "$2}'
-mindepth 1
– toxalot 10.03.2014, 06:20-printf '\n'
вместо-exec echo
. – toxalot 10.03.2014, 13:06-printf
, но не, если Вы хотите, чтобы это работало над FreeBSD, например. – Shawn J. Goff 10.03.2014, 14:07