Как показать только скрытые файлы в Терминале?


154

У меня есть каталог, который содержит тысячи файлов, некоторые из них скрыты.

Команда выводит ls -aсписок всех файлов, включая скрытые, но мне нужно просто перечислить скрытые файлы.

Какую команду я должен использовать?


1
Просто ls -ld .*или ls -ald .*будет работать
Джон Струд

Ответы:


189

Команда :

ls -ld .?* 

Будет только список скрытых файлов.

Объясните:

 -l     use a long listing format

 -d, --directory
              list  directory entries instead of contents, and do not derefer‐
              ence symbolic links

.?* will only state hidden files 

8
Вам не нужны эти два вопросительных знака, * их закрывает (? Соответствует только одному символу, * соответствует любому их числу).
psusi

13
@psusi, я думаю, что цель состоит в том, чтобы исключить .и ..из матча. Однако это также исключает (вполне законные) односимвольные скрытые имена файлов , таких как .a, .1и так далее. Возможно, лучшим расширенным глобусом будет, .!(|.)например, буквальная точка, за которой следует что угодно, кроме ничего или другой (единственной) точки, т.е.ls -d .!(|.)
steeldriver

@steeldriver, аккуратный, ?? версия исключает "." а также "..". Это, кажется, результат интересной причуды: ни один? ни * не будет соответствовать точке, но? должен совпадать с чем-либо, иначе имя игнорируется.
psusi

Для идентификации каталогов и файлов добавьте опцию F, т. Е. Имена каталогов ls -ldF.? * Имеют символ "/", а файлы последних отображаемых символов - нет.
RCF

1
Это почти работает, кроме списка скрытых папок, таких как .vim, который я здесь не рассматриваю. Я изменяю это немного как ls -ldp.? * | grep -v / Это только список скрытых файлов, а не скрытой папки
Фред Ян

31
ls -d .!(|.)

Делает именно то, что ищет OP.


1
Как это работает?
SarcasticSully

список каталогов что-нибудь с. и не перечисляйте ничего без того, во что это в значительной степени переводится.
Патрик

1
Я понимаю, что в !(pattern-list), pattern-listэто список из одного или нескольких шаблонов, разделенных символом a |, но меня смущает, что слева от вас нет шаблона |. Не могли бы вы объяснить мне этот синтаксис?
Карлос Мендоса,

2
@CarlosMendoza, который станет пустым шаблоном, поэтому за ним .не следует (ничего или .), исключая .себя и ...
Муру

16

Если вы просто хотите, чтобы файлы в вашем текущем каталоге (без рекурсии), вы можете сделать

echo .[^.]*

При этом будут напечатаны имена всех файлов, имя которых начинается с .символа « a» и сопровождается одним или несколькими точечными символами. Обратите внимание, что это не удастся для файлов, имя которых начинается с последовательных точек, поэтому, например ....foo, не будет отображаться.

Вы также можете использовать find:

find -mindepth 1 -prune -name '.*'

В -mindepthгарантирую , что мы не соответствуем .и -pruneсредствам , которые findне сойдут в подкаталоги.



4

Используя findи awk,

find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

Объяснение:

find . -type f -> Вывести список всех файлов в текущем каталоге вместе с его путем, как,

./foo.html
./bar.html
./.foo1

awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

/в качестве разделителя полей awk проверяет последнее поле, начиная с точки или нет. Если он начинается с точки, то он печатает последнее поле этой соответствующей строки.


Вы могли бы просто использовать find -type f. Вам не нужно явно указывать путь поиска или -name "*".
Тердон

3

find обычно это лучший вариант для сложных поисков, чем использование подстановки имен.

find . -mindepth 1 -maxdepth 1 -name '.*'

или же

find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'

find . ищет в текущем каталоге

-mindepth 1исключает . и .. из списка

-maxdepth 1 ограничивает поиск текущим каталогом

-name '.*' найти имена файлов, которые начинаются с точки

-o или же

-name '*~' найти имена файлов, заканчивающиеся тильдой (обычно это файлы резервных копий из программ редактирования текста)

Тем не менее, этот и все другие ответы пропускают файлы, которые находятся в .hiddenфайле текущего каталога . Если вы пишете скрипт, то эти строки будут читать .hiddenфайл и отображать имена файлов тех, которые существуют.

if [[ -f .hidden]] # if '.hidden' exists and is a file
then
    while read filename # read file name from line
    do
        if [[ -e "$filename" ]] # if the read file name exists
        then
            echo "$filename" # print it
        fi
    done < .hidden # read from .hidden file
fi

Что за .hiddenфайл? Зачем вообще нужен .hiddenфайл с именами? Во всяком случае, если есть один, почему вы делаете что-то такое сложное, когда все, что вам нужно будет cat .hidden? Ваша findкоманда верна (ish), но не -name '*~'имеет значения. Файлы, оканчивающиеся на тильды, являются файлами резервных копий, но никак не скрыты.
Тердон

@terdon .hiddenФайл предназначен для файлов и папок, которые вы хотите скрыть, если вы не можете изменить имя файла / папки, чтобы начать с точки. Что касается файлов, оканчивающихся на тильды, это зависит от системы. ls -Bбудет игнорировать такие файлы, как и большинство исследователей файлов с графическим интерфейсом.
Марк Х

cat .hiddenможет показывать файлы, которые больше не существуют, если эти файлы были удалены или перемещены после добавления в .hiddenфайл.
Марк Х

Это хорошо работает.
Пенге Гэн

2

Я думаю, что вы можете сделать это с помощью следующей команды.

ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"

ls -a введенная вами команда, которая показывает все файлы и каталоги в текущем рабочем каталоге.

grep "^\."добавленная команда, которая фильтрует вывод, показывает только скрытые файлы (название начинается с ".").

grep -v "^\.$" | grep -v "^\..$" добавлена ​​команда, которая фильтрует вывод для исключения., .. (Это текущий и родительский каталог).

Если некоторые имена файлов могут содержать более одной строки "\n", приведенный выше пример может быть неправильным.

Поэтому я предлагаю следующую команду, чтобы решить эту проблему.

find -maxdepth 1 -name ".[!.]*"


@ RaduRădeanu Я видел твой комментарий, это так хорошо. Я снова отредактировал свой ответ. Спасибо за ваш комментарий.
xiaodongjie

2

Что еще вы могли бы сделать, is ls .?*или ls .!(|)это покажет вам все в текущем каталоге скрытых файлов / каталогов вверху и других файлов / каталогов ниже

например: из моего терминала

$ ls .?*       
.bash_history    .dmrc        .macromedia   .weather
.bash_logout     .gksu.lock   .profile      .wgetrc
.bash_profile    .bashrc.save .ICEauthority .toprc           .Xauthority
.bashrc          .lastdir     .viminfo      .xsession-errors
.bashrc~         .dircolors   .lynxrc       .vimrc           .xsession-errors.old

..:
Baron

.adobe:
Flash_Player

.aptitude:
cache  config

.cache:
compizconfig-1                              rhythmbox
dconf                                       shotwell

Теперь обратите внимание на результаты выше, он показывает вам каждый файл / dir с его subdir и скрытыми файлами прямо ниже.

[1:0:248][ebaron@37signals:pts/4][~/Desktop]
$ ls .!(|)
.bash_aliases  .bashrc1  .bashrc1~

..:
askapache-bash-profile.txt  examples.desktop             Public           top-1m.csv
backups             Firefox_wallpaper.png        PycharmProjects          top-1m.csv.zip
Desktop             java_error_in_PYCHARM_17581.log  Shotwell Import Log.txt  topsites.txt
Documents           Music                Templates            Videos
Downloads           Pictures                 texput.log           vmware

Извините, я не могу комментировать. чтобы объяснить разницу между здесь ls .?*и @ cioby23 ответ ls -d .[!.]* .??*А почему это на самом деле печатать скрытые файлы в два раза , потому что буквально вы спрашиваете дважды .??*, .?*, .[!.]*они то же самое, так что добавление любого из них с различными символами команды будут печатать в два раза.


1

Вы также можете использовать:

ls -d .[!.]* .??*

Это позволит вам отображать обычные скрытые файлы и скрытые файлы, которые начинаются с 2 или 3 точек, например: ..hidden_file


1
При этом я получаю все скрытые файлы дважды.
TuKsn

1

вы можете использовать команду

ls -Ad .??*

Это имеет преимущество, заключающееся в том, что в список разрешается многостолбцовый список, в отличие от подхода на основе grep в ls -a | grep "^\."решениях.


1

Все ответы на данный момент основаны на том факте, что файлы (или каталоги), имена которых начинаются с точки, являются «скрытыми». Я придумал другое решение, которое может быть не столь эффективным, но оно не предполагает ничего о именах скрытых файлов и поэтому избегает перечисления ..в результате (как и принятый в настоящее время ответ).

Полная команда:

ls -d $(echo -e "$(\ls)\n$(\ls -A)" | sort | uniq -u)

объяснение

Это делает список всех файлов (и каталогов) дважды,

echo -e "$(\ls)\n$(\ls -A)"

но показывает скрытые файлы только один раз -A.

Затем список сортируется, в результате | sortчего обычные (невидимые) файлы появляются дважды и рядом друг с другом.

Затем удалите все строки, которые появляются более одного раза | uniq -u, оставляя только уникальные строки.

Наконец, используйте lsснова, чтобы получить список всех файлов с пользовательскими настройками пользователя и без перечисления содержимого каталогов в списке -d.

РЕДАКТИРОВАТЬ (Ограничения):

Как указал muru, это решение не будет работать правильно, если есть файлы с именами, например, escaped\ncharacter.txtпотому echo -eчто разделит имя файла на две строки. Он также не будет работать должным образом, если есть два скрытых файла с почти одинаковыми именами, за исключением специального символа, такого как .foo[tab].txtи .foo[new-line].txtоба из которых печатаются как .foo?.txtи будут удаленыuniq -u


1
Я думаю, что это в значительной степени определение скрытых файлов. Даже происхождение этих скрытых файлов происходит от ошибки, связанной с .первым символом.
Муру

Я упоминаю это (как факт) в первом абзаце. Тем не менее, он все же получает другой результат, чем текущий принятый ответ
alejandro

Конечно, это исключает .., но мне интересно, насколько хорошо это работает с именами файлов, содержащими специальные символы.
Муру

Я не знаю точно, что вы подразумеваете под специальными символами, но я думаю, что это не создаст проблемы, так как в этом решении ничего не говорится о именах файлов
alejandro

На самом деле, вы предполагаете, по крайней мере, одну вещь: в именах файлов нет новых строк. Также: в именах файлов нет escape-последовательностей, которые echo -eбудут интерпретироваться. Также: lsне будет искажать имена файлов, так что два разных имени файла будут отображаться одинаково (например, в некоторых версиях lsбудут использоваться ?специальные символы, поэтому .foo\tbar( \t=> tab) и .foo\nbar( \n=> newline) оба будут отображаться как foo?bar).
Муру

1

Кроме того, вы также можете использовать echo .*

например

user@linux:~$ echo .*
. .. .bash_aliases .bash_history .bash_logout .bashrc
user@linux:~$

Если вы предпочитаете формат длинного списка, просто преобразуйте пробел в новую строку.

user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$ 

0

При использовании bash установка GLOBIGNOREспециальной переменной - это не пустое значение, чтобы игнорировать его .и ..при расширении глобусов. Из документации Bash :

GLOBIGNOREПеременной оболочки могут быть использованы для ограничения множества имен файлов , соответствующих шаблону. Если GLOBIGNOREустановлено, каждое совпадающее имя файла, которое также соответствует одному из шаблонов, GLOBIGNOREудаляется из списка совпадений. Если nocaseglobопция установлена, сопоставление с шаблонами в GLOBIGNOREвыполняется без учета регистра. Имена файлов .и ..всегда игнорируются, когда GLOBIGNOREустановлено и не равно нулю. Однако установка GLOBIGNOREненулевого значения приводит к включению опции оболочки dotglob, поэтому все остальные имена файлов, начинающиеся с ‘.', будут совпадать.

Если мы установим его .:.., оба .и ..будут игнорироваться. Так как установка этого значения на ненулевое значение также приведет к такому поведению, мы могли бы также установить его на.

Так:

GLOBIGNORE=.
ls -d .*
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.