Листинг только каталогов, использующих ls в bash: экзамен

эта команда перечисляет каталоги в текущем пути:ls -d */

что именно делает шаблон */ сделать?

и как мы можем дать абсолютный путь в команды (например,ls -d /home/alice/Documents) для перечисления только каталогов в этом пути?

22 ответов


*/ - это шаблон, который соответствует всем подкаталогам в текущем каталоге (* будет соответствовать все файлы и подкаталогов; на / ограничивает его в каталогах). Аналогично, чтобы перечислить все подкаталоги в разделе /home/alice / Documents, используйте ls -d /home/alice/Documents/*/


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

1. Используя echo

пример: echo */, echo */*/
Вот что я получил:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. Используя ls только

пример: ls -d */
Вот именно то, что я получил:

cs/     files/      masters/  
draft/  hacks/      static/  

или список (с подробной информацией): ls -dl */

3. Используя ls и grep

пример: ls -l | grep "^d" Вот что я got:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Скрипт Bash (не рекомендуется для имени файла содержать пробел.)

пример: for i in $(ls -d */); do echo ${i%%/}; done
Вот что я получил:

cs  
draft  
files  
hacks  
masters  
static

если вы хотите иметь ' / ' в качестве конечного символа, команда будет:for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

Я использую:

ls -d */ | cut -f1 -d'/'

Это создает один столбец без Слэша - полезно в сценариях.

мои два цента.


все папки без подпапки:

find /home/alice/Documents -maxdepth 1 -type d

все папки С подпапки:

find /home/alice/Documents -type d

4 (больше) надежных варианта.

An без кавычек звездочка * будет интерпретироваться как шаблон (glob) оболочкой.
оболочка будет использовать его в расширении пути.
затем он будет генерировать список файлов, которые соответствуют шаблону.
простая звездочка будет соответствовать всем именам файлов в PWD (настоящий рабочий каталог).
более сложный шаблон, как */ будет соответствовать всем именам файлов, которые заканчиваются на /.
таким образом, все справочники. Вот почему команда:

1.- эхо.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"

будет расширен (оболочкой) до echo все каталоги в PWD.


чтобы проверить это: создайте каталог (mkdir) назван как test-dir, и cd в:

mkdir test-dir; cd test-dir

создать несколько каталогов:

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:

команда echo ./*/ останется надежным даже с нечетными именованными файлами:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

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


если вместо echo, мы используем ls, оболочка по-прежнему расширяет список имен файлов. Оболочка является причиной получения списка каталогов в PWD. The до ls делает его список текущей записи каталога вместо содержимого каждого каталога (как представлено по умолчанию).

ls -d */

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

2.- ls

в GNU ls примет "конец настройки" (-- ключ).

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls

3.- printf

чтобы перечислить каждый каталог в отдельной строке (в одном столбце, аналогичном ls -1), используйте:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

и, еще лучше, мы могли бы удалить трейлинг /:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

An попробуйте так:

$ for i in $(ls -d */); do echo ${i%%/}; done

приведет к ошибке:

  • некоторые имена (ls -d */) как уже было показано выше.
  • будет зависеть от значения IFS.
  • разделит имена на пробелы и вкладки (по умолчанию IFS).
  • каждая новая строка в имени запустит новую команду echo.

4.- Функция

наконец, использование списка аргументов внутри функции не повлияет на аргументы список текущей запущенной оболочки. Просто:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

представляет этот список:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

эти параметры безопасны с несколькими типами нечетных имен файлов.


на tree команда также очень полезна здесь. По умолчанию он покажет все файлы и каталоги на полную глубину, с некоторыми символами ascii, отображающими дерево каталогов.

$ tree
.
├── config.dat
├── data
│   ├── data1.bin
│   ├── data2.inf
│   └── sql
|   │   └── data3.sql
├── images
│   ├── background.jpg
│   ├── icon.gif
│   └── logo.jpg
├── program.exe
└── readme.txt

но если бы мы хотели получить только каталоги, без дерева ascii и с полным путем из текущего каталога, вы могли бы сделать:

$ tree -dfi
.
./data
./data/sql
./images

доводы являются:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

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

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

и ограничить количество подкаталогов, вы можете установить максимальный уровень подкаталогов с -L level, например:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

больше аргументов можно увидеть с помощью человек-дерево


в случае, если вам интересно, почему вывод из ' ls-d */' дает вам два косые черты, например:

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//

Это, вероятно, потому, что где-то ваша оболочка или файлы конфигурации сеанса псевдоним команды ls к версии ls, которая включает флаг-F. Этот флаг добавляет символ к каждому выходному имени (это не простой файл), указывающий, что это такое. Таким образом, одна косая черта-от соответствия шаблону'*/', а другая косая черта-добавленный тип указатель.

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

\ls-d */


Я просто добавляю это к моему .bashrc файл (вы также можете просто ввести его в командной строке, если вам нужно/нужно только для одного сеанса)

alias lsd='ls -ld */'

тогда ЛСД даст желаемый результат.


Если скрытый каталог не требуется перечислять, я предлагаю:

ls -l | grep "^d" | awk -F" " '{print }'  

и если скрытые каталоги необходимо перечислить, используйте:

ls -Al | grep "^d" | awk -F" " '{print }'

или

find -maxdepth 1 -type d | awk -F"./" '{print }'

Показать список папок без /

ls -d */|sed 's|[/]||g'

вот что я использую

ls -d1 /Directory/Path/*;


фактический ls решение, включая символические ссылки в каталогах

многие ответы здесь на самом деле не используют ls (или использовать его только в тривиальном смысле ls -d, при использовании подстановочных знаков для фактического сопоставления подкаталогов. Истинный ls решение полезно, Так как оно позволяет использовать ls варианты для сортировать заказ, etc.

исключая символические ссылки

одно решение с использованием ls было дано, но он делает что-то отличное от другого решения в том, что он исключает символические ссылки в каталогах:

ls -l | grep '^d'

(возможно, трубопровод через sed или awk изолировать имена файлов)

включая символические ссылки

в (возможно, более распространенном) случае, когда символические ссылки на каталоги должны быть включены, мы можем использовать на ls:

ls -1p | grep '/$'

или, избавляясь от косых черт:

ls -1p | grep '/$' | sed 's/\/$//'

мы можем добавить опции в ls as необходимо (если используется длинный список,-1 больше не требуется).

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

ls -1p | grep -P '(?=/$)'

проверьте, является ли элемент каталогом с test -d:

for i in $(ls); do test -d $i && echo $i ; done

однострочный список каталогов только из "здесь".

с подсчетом файлов.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done

*/ - шаблон сопоставления файлов, который соответствует каталогам в текущем каталоге.

чтобы перечислить только каталоги, мне нравится эта функция:

# long list only directories
llod () { 
  ls -l --color=always "$@" | grep --color=never '^d'
}

положите его в ваш .bashrc следующее.

примеры использования:

llod       # long listing of all directories in current directory
llod -tr   # same but in chronological order oldest first
llod -d a* # limit to directories beginning with letter 'a'
llod -d .* # limit to hidden directories

Примечание: он сломается, если вы используете . Вот что:

# long list only directories
llod () { 
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}

FYI, если вы хотите напечатать все файлы в многострочном режиме, вы можете сделать ls -1 которая будет печатать каждый файл в отдельной строке. файл1 файл2 файл file3


Использование Perl:

ls | perl -nle 'print if -d;'

только для листинга каталоги:

ls -l | grep ^d

для перечисления только файлы:

ls -l | grep -v ^d 

или же вы можете сделать как: ls-ld */


Я частично решил с помощью:

cd "/path/to/pricipal/folder"

for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

ln: «/home/inukaze/./.»: can't overwrite a directory
ln: «/home/inukaze/../..»: can't overwrite a directory
ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

Ну, это сводится ко мне, мэру часть:)


добавление, чтобы сделать его полным кругом, чтобы получить путь к каждой папке, используйте комбинацию ответа Альберта, а также Горданов, которые должны быть довольно полезными.

for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done

выход:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/

попробуйте этот. это будет работать на всех дистрибутивах ls-ltr / grep drw


file *|grep directory

O /P (на моей машине) --

[root@rhel6 ~]# file *|grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

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

file *|grep directory|cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir

* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1