Как исключить файлы. и.. используя ls или find?

Решение проблемы было очень простым. Он сказал «По умолчанию», потому что я пытался войти с именем пользователя «По умолчанию», а не с моим именем пользователя. Мне просто нужно было нажать на свое имя.

Почему и когда был создан Пользователь по умолчанию или его цель, я понятия не имею.

3
01.12.2020, 11:04
5 ответов

Используйте только ! -path.. Пути, по которым findвыполняет свои тесты, относятся к пути поиска, который вы используете, и каталог .будет отображаться как просто .до findв вашей примерной команде. Если бы вы использовали любой другой путь поиска, вы бы использовали его в тесте, чтобы не указывать его (, например.find "$HOME" ! -path "$HOME").

Также обратите внимание, что при использовании wc -lвы на самом деле подсчитываете не файлы, а количество строк, созданных find, которое может быть больше, чем количество файлов, если какое-либо имя содержит символы новой строки.

С POSIX findвы можете использовать

find. ! -path. -prune -exec echo x \; | wc -l 

для подсчета количества имен в текущем каталоге. Здесь -pruneпредотвратит вход findв какие-либо подкаталоги, а -exec echo x \;выведет символ xв строке для каждого найденного имени. Затем эти строки будут подсчитаны с помощью wc -l.

Чтобы не отображать .или ..с ls, используйте ls -Aвместо ls -a.


Другой способ подсчета имен в одном каталоге, который позволяет использовать все возможные имена файлов, это

shopt -s dotglob nullglob
set -- *
echo "$#"

... в bashили

set -- *(DN)
echo $#

... в zsh(, где (DN)изменяет поведение *, чтобы оно также соответствовало скрытым именам и чтобы шаблон полностью удалялся, если нет совпадений, очень похоже на эффект включения dotglobи nullglobпараметры оболочки в bash).

Обе эти части кода устанавливают позиционные параметры в список имен в текущем каталоге, включая скрытые имена. Как только это будет сделано, количество установленных позиционных параметров находится в специальной переменной $#.

Подстановочный шаблон *не соответствует ни ., ни ... Даже когда его просят сопоставить скрытые имена.

В оболочке yashустановка параметра оболочки dot-globс set -o dot-globприводит к тому, что *соответствует скрытым именам, включая как ., так и ... вычтите 2 из значения $#, если вы используете эту оболочку.

5
18.03.2021, 22:46

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

find. -maxdepth 1 ! -path. | wc -l
find "$HOME" -maxdepth 1 ! -path "$HOME" | wc -l

(до тех пор, пока $HOMEне содержит символов, которые могут быть интерпретированы как символы шаблона, , то есть *, ?,[]). Вы также можете сопоставить только имя ., добавив его (, если необходимо, )к интересующему вас пути :

.
find. -maxdepth 1 ! -name. | wc -l
find "$HOME"/. -maxdepth 1 ! -name. | wc -l

Для точного подсчета файлов, найденных с помощью find, вы должны подсчитывать что-то кроме имен файлов (, которые могут включать новые строки ), , например. , если ваш findподдерживает-printf:

find. -maxdepth 1 ! -name. -printf 1 | wc -c

или,с POSIX find, используя трюк //:

find.//. -maxdepth 1 ! -name. | grep -c //

..не является проблемой с find, он не включает его, если вы не добавите его явно(find..... ).

lsне будет отображать .и ..по умолчанию; если вы хотите видеть скрытые файлы, но не .и .., используйте опцию -Aвместо -a. С помощью GNU lsвы можете попросить его заключать в кавычки специальные символы, что позволит вам точно подсчитывать файлы :

.
ls -q1A. | wc -l
8
18.03.2021, 22:46

использовать-mindepth:

find. -mindepth 1 -maxdepth 1    |wc -l
10
18.03.2021, 22:46

POSIXly:

find. ! -name. -prune | LC_ALL=C grep -c /

Использование wc -lнедопустимо, так как оно подсчитывает символы новой строки, которые будут включать символы, напечатанные findдля разделения имен файлов, а также символы в самих именах файлов (, поскольку имена файлов могут содержать любое значение байта, кроме 0 и тот, что представляет/).

С другой стороны, должен быть один и только один /для каждого имени файла в выводе find.

grepпоскольку это текстовая утилита, а имена файлов представляют собой любую произвольную последовательность байтов, нам нужно LC_ALL=C, чтобы убедиться, что любая последовательность байтов формирует допустимые символы, чтобы гарантировать детерминированное поведениеgrep(имена файлов, как правило, также гарантированно меньше чем максимальная длина строки, поддерживаемая реализациями grep).

Другим вариантом может быть:

LC_ALL=C ls -Aq | wc -l

хотя -Aдля включения скрытых файлов, но не .и ..— относительно недавнее дополнение к стандарту POSIX. Также обратите внимание, что busybox lsв настоящее время не поддерживает -q(, необходимые здесь, чтобы символы новой строки в именах файлов отображались как ?, поэтому они не учитываютсяwc -l).

Для любого произвольного каталога, путь которого хранится в переменной, вы должны запустить (CDPATH= cd -P -- "$dir" && find/ls command above) |..., хотя обратите внимание, что это не будет работать должным образом для файла с именем-(или, в зависимости от реализации cdтаких вещей, как -1, +2... ), к которым вам нужно обратиться, добавив к ним ./.

4
18.03.2021, 22:46

Самый простой. Работает. Может быть, не со встроенными символами новой строки в именах файлов, но поскольку это такие ужасные стандарты, я бы сказал, переименуйте эти файлы.

ls -d * | wc -l
3
18.03.2021, 22:46

Теги

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