Эта команда перечисляет каталоги в текущем пути: ls -d */
Что именно делает шаблон */
?
И как мы можем дать абсолютный путь в приведенной выше команде (например, ls -d /home/alice/Documents
) для перечисления только каталогов в этом пути?
Эта команда перечисляет каталоги в текущем пути: ls -d */
Что именно делает шаблон */
?
И как мы можем дать абсолютный путь в приведенной выше команде (например, ls -d /home/alice/Documents
) для перечисления только каталогов в этом пути?
*/
- это шаблон, который соответствует всем подкаталогам в текущем каталоге (*
будет соответствовать всем файлам и подкаталогам; /
ограничивает его в каталогах). Аналогично, чтобы перечислить все подкаталоги в /home/alice/Documents, используйте ls -d /home/alice/Documents/*/
echo
Пример: echo */
, echo */*/
Вот что я получил:
cs/ draft/ files/ hacks/ masters/ static/
cs/code/ files/images/ static/images/ static/stylesheets/
ls
Пример: ls -d */
Вот именно то, что я получил:
cs/ files/ masters/
draft/ hacks/ static/
Или в виде списка (с подробной информацией): ls -dl */
ls
и grep
Пример: ls -l | grep "^d"
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
Пример: for я in $(ls -d */); do echo ${i%%/}; done
for я in $(ls -d */); do echo ${i%%/}; done
Вот что я получил:
cs
draft
files
hacks
masters
static
Если вы хотите, чтобы конечным символом был символ '/', команда будет: for я in $(ls -d */); do echo ${i}; done
for я 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
Неизвестная звездочка *
будет интерпретироваться как шаблон (glob) оболочкой.
Оболочка будет использовать его в расширении пути.
Затем он сгенерирует список имен файлов, соответствующих шаблону.
Простая звездочка будет соответствовать всем именам файлов в PWD (настоящий рабочий каталог).
Более сложный шаблон как */
будет соответствовать всем именам файлов, которые заканчиваются на /
.
Таким образом, все каталоги. Вот почему команда:
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. Опция -d
для ls
делает ее списком текущей записи каталога, а не содержимым каждой директории (как указано по умолчанию).
ls -d */
Однако эта команда (несколько) менее надежна. Он не будет работать с нечетными указанными файлами, перечисленными выше. Он задушит несколькими именами. Вам нужно стереть один за другим, пока не найдете те, у кого проблемы.
GNU ls
примет ключ "конец опций" (--
).
ls -d ./*/ ### more reliable BSD ls
ls -d -- */ ### more reliable GNU ls
Чтобы перечислить каждый каталог в своей строке (в одном столбце, аналогичном 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
).Наконец, использование списка аргументов внутри функции не повлияет на список аргументов текущей запущенной оболочки. Просто:
$ 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
Дополнительные аргументы можно увидеть с помощью man tree
В случае, если вам интересно, почему вывод из 'ls -d */' дает вам две завершающие косые черты, например:
[prompt]$ ls -d */
app// cgi-bin// lib// pub//
это, вероятно, потому, что где-то ваши файлы конфигурации оболочки или сеанса имеют псевдоним команды ls для версии ls, которая включает в себя флаг -F. Этот флаг добавляет символ в каждое имя вывода (это не простой файл), указывающий на то, что он есть. Таким образом, одна косая черта - это совпадение с шаблоном '*/', а другая косая черта - индикатор добавленного типа.
Чтобы избавиться от этой проблемы, вы могли бы, конечно, определить другой псевдоним для ls. Однако, чтобы временно не вызывать псевдоним, вы можете добавить команду с обратной косой чертой:
\ ls -d */
Я просто добавлю это в мой .bashrc
файл (вы также можете просто ввести его в командной строке, если вам нужно только его для одного сеанса)
alias lsd='ls -ld */'
то lsd даст желаемый результат.
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 '(?=/$)'
Если скрытый каталог не требуется для перечисления, я предлагаю:
ls -l | grep "^d" | awk -F" " '{print $9}'
И если необходимо указать скрытые каталоги, используйте:
ls -Al | grep "^d" | awk -F" " '{print $9}'
ИЛИ
find -maxdepth 1 -type d | awk -F"./" '{print $2}'
для отображения списков папок без /
ls -d */|sed 's|[/]||g'
Для просмотра только каталогов:
ls -l | grep ^d
для просмотра только файлов:
ls -l | grep -v ^d
или также вы можете сделать как: ls -ld */
Вот что я использую
ls -d1 /Directory/Path/*;
Проверьте, является ли элемент каталогом с 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 "[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'
}
FYI, если вы хотите распечатать все файлы в многострочном режиме, вы можете сделать ls -1
, который будет печатать каждый файл в отдельной строке.
file1
file2
файл3
Использование Perl:
ls | perl -nle 'print if -d;'
Попробуй это. Это работает для всех дистрибутивов Linux.
ls -ltr | grep drw
Простой список текущего каталога, это будет:
ls -1d ./*/
Вы хотите, чтобы это было отсортировано и чисто?
ls -1d ./*/ | cut -c 3- | rev | cut -c 2- | rev | sort
Помните: заглавные буквы имеют различное поведение в сортировке
Я частично решил с помощью:
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
Ну, это уменьшит мне часть мэра:)
Добавляя, чтобы сделать полный круг, чтобы получить путь к каждой папке, используйте комбинацию ответа Альберта, а также Gordans, которая должна быть довольно полезной.
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
как таковым; это делается shell/Bash, в процессе, известном как globbing.
Вот почему echo */
и ls -d */
выводят одинаковые элементы. (Флаг -d
заставляет ls
выводить имена каталогов, а не содержимое каталогов.)
Вот вариант с использованием дерева, который выводит имена каталогов только в отдельных строках, да, это некрасиво, но эй, это работает.
tree -d | grep -E '^[├|└]' | cut -d ' ' -f2
или с помощью awk
tree -d | grep -E '^[├|└]' | awk '{print $2}'
Это, вероятно, лучше, и он сохранит /
после имени каталога.
ls -l | grep "^d" | awk '{print $9}'
Самая короткая команда из всех (на самом деле хак) для перечисления только каталогов. Введите абсолютный путь или относительный путь интересующего каталога. Введите CD и нажмите вкладку. Отображаются только каталоги.
$ cd
Самый короткий действительно.
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 permitted
file - determine file type
grep - searches for string named directory
-d - to specify a field delimiter
-f1 - denotes field 1
Вот что я использую для перечисления только имен каталогов:
ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"