Для университетского проекта мне нужно сосчитать все файлы в папке. Я использовал команду:
find ./dirName | wc -l
Хотя, когда я сравниваю это с количеством файлов, предоставленным Nautilus, это значительно больше. Смотрите скриншот ниже:
./ dirName - это фактически каталог файлов из репозитория (SVN / GIT), и мне нужно выяснить, сколько файлов составляют до системы.
Может ли кто-нибудь объяснить, почему возникают эти различия, и, возможно, сказать мне, какой из них является более надежным?
Файлы и каталоги, начинающиеся с точки (.
), скрыты в Linux. Sup>
Действия для воспроизведения:
mkdir somedir && cd somedir
touch .hidden .hidden2 regular regular2 # 4 files, 2 hidden
find . | wc -l # outputs 5 (4 files + dir itself)
Наутилус сообщает: [ 1110] Содержимое: 2 элемента, всего 0 байт
Вот краткая демонстрация количества файлов для метаданных, используемых в Git, все в каталоге .git
.
git init myrepo # Initialized [...] in myrepo/.git/
cd myrepo/
find . | wc -l # outputs 23! for an empty repository
tree -a # outputs 10 directories, 12 files
echo "have to add something for git ls-tree" > somefile
git add somefile && git commit -m "Initial commit"
find . | wc -l # outputs 38 (!)
git ls-tree -r HEAD | wc -l # outputs 1
А также Наутилус сообщает 1 там.
tree
Как указал Жиль в свой ответ , использование find
и передача его в wc
не слишком надежны, если имена файлов содержат специальные символы.
Кажется, что tree
способен сделать это правильно:
tree -a
.
├── dir
│ └── regular3
├── dir2
├── .hidden
├── .hidden2
├── regular
└── regular2
2 directories, 5 files
Там могут быть имена файлов с символами новой строки. Весьма нецелесообразно, но технически возможно. Это может быть то, что ваше упражнение было.
Один из способов надежного подсчета файлов в каталоге - это заставить find
напечатать что-то, что может быть надежно подсчитано, то есть с одним элементом на файл.
find ./dirName -printf a | wc -c
blockquote>Имейте в виду, что
find
включает в себяdirName
и возвращается в подкаталоги.Если вы хотите, чтобы файлы были только в
dirName
, без повторения, пусть оболочка подсчитает их:GLOBIGNORE=.:.. set -- * echo $#
Попробуйте проверить выходные данные find
:
find somewhere | less
. Вы увидите, что find
по умолчанию выводит любой тип файла, не делая различий на основе типа или имени. Вместо этого Nautilus не считает начальный каталог (в данном примере somewhere
) или файлы, которые он не отображал при просмотре.
Чтобы решить эту проблему, используйте опцию -type
find:
find somewhere -type f | wc -l
find somewhere ! -type d | wc -l
В первой строке будут искать все обычные файлы. Второй - все не-директивные элементы (то есть обычные файлы, блочные устройства, сокеты UNIX и т. Д.). См. man find
для получения дополнительной информации.
Возможно, вас заинтересует чтение статей -H
, -L
и -P
, которые управляют тем, как find
должен обрабатывать символические ссылки (и, следовательно, как символические ссылки влияют на количество).