it-swarm.com.ru

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

Эта команда выводит список каталогов по текущему пути: ls -d */

Что именно делает шаблон */?

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

791
Sibi

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

843
Gordon Davisson

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

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" Вот что я получил:

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 Script (не рекомендуется для имени файла, содержащего пробелы)

Пример: 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/
423
Albert

Я использую:

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

Это создает один столбец без косой черты - полезно в сценариях.

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

80
Thomas Altfather Good

Для всех папок без подпапок:

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

Для всех папок с вложенных папок:

find /home/alice/Documents -type d
46
at3m

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

без кавычек asterisk * будет интерпретироваться Shell как шаблон (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, то Shell по-прежнему является тем, что расширяет список имен файлов. Оболочка является причиной для получения списка каталогов в PWD. Параметр -d для 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.

Попытка как это:

$ 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

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

32
user2350426

Команда 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

Больше аргументов можно увидеть с помощью man tree

16
Hamish Downer

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

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

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

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

\ ls -d * /

11
gwideman

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

alias lsd='ls -ld */'

тогда lsd выдаст желаемый результат.

9
guesty guesterson

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

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

И если нужно перечислить скрытые каталоги, используйте:

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

OR

find -maxdepth 1 -type d | awk -F"./" '{print $2}'
7
PHP Learner

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

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

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

ls -l | grep ^d

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

ls -l | grep -v ^d 

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

6
Vijay Gawas

Актуальное решение ls, включая символические ссылки на каталоги

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

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

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

ls -l | grep '^d'

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

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

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

ls -1p | grep '/$'

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

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

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

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

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

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

ls -d1 /Directory/Path/*;

5
Banning

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

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

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

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

# long list only directories
llod () { 
  ls -l --color=always "[email protected]" | 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

ПРИМЕЧАНИЕ: он сломается, если вы используете опцию -i. Вот исправление для этого:

# long list only directories
llod () { 
  ls -l --color=always "[email protected]" | egrep --color=never '^d|^[[:digit:]]+ d'
}
2
Robin A. Meade

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

2
warfreak92

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

С количеством файлов.

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

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

ls | Perl -nle 'print if -d;'
2
Paul-Gerhard Woolcock

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

1
Raj RD

Я частично решил с:

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

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

1
inukaze

Чтобы ответить на исходный вопрос, */ не имеет ничего общего с ls per se; это делается Shell/Bash в процессе, известном как globbing .

Вот почему echo */ и ls -d */ выводят одинаковые элементы. (Флаг -d заставляет ls выводить имена каталогов, а не содержимое каталогов.)

1
flow2k

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

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/
1
BilliAm

Простой список текущего каталога, это будет:

ls -1d ./*/

Вы хотите, чтобы это было отсортировано и чисто?

ls -1d ./*/ | cut -c 3- | rev | cut -c 2- | rev | sort
0
PYK

Вот что я использую для перечисления только имен каталогов:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"
0
Robert Lujo
file *|grep directory

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

[[email protected] ~]# 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
0
AVS