Как вывести только файлы, а не каталоги каталога Bash?

87

Как я могу перечислить все файлы одной папки, но не их папки или субфайлы. Другими словами: как я могу перечислить только файлы?

Родриго
источник

Ответы:

118

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

find . -maxdepth 1 -type f

Использование этой -maxdepth 1опции гарантирует, что вы будете просматривать только текущий каталог (или, если вы замените .какой-либо путь, этот каталог). Если вам нужен полный рекурсивный список всех файлов в этом и подкаталогах, просто удалите эту опцию.

Carlpett
источник
После моего комментария к ответу mklement0 я понял, что «find ./*.png -maxdepth 1 -type f> pngs.txt», вероятно, даст то же самое. Оно делает. Без установки скрипта.
Alex Hall
2
findна mac нет ни -type, ни -maxdepthопций.
Тимофей
1
@Tim: -typeи -maxdepthне являются вариантами в обычном смысле слова; BSD find(как используется в OS X) называет их первичными , и они должны идти после операнда (ов) имени файла ( .в этом случае; обратите внимание, что, в отличие от Linux, версия BSD требует по крайней мере одного явного операнда имени файла); команда в этом ответе определенно работает на Mac.
mklement0 07
1
@AlexHall: Это умное решение (хотя я предлагаю find *.png -maxdepth 0 -type fизбегать ./префикса в именах выходных файлов; также обратите внимание на -maxdepthof 0, а не 1), пока все, что вам нужно, это имена файлов в алфавитном порядке . Если вы хотите, что в lsпротивном случае может сделать для вас (другой формат вывода / порядок, встроенный контроль над включением скрытых элементов или нет), дополненный фильтрацией [multi-] типов, сценарий из моего ответа может помочь.
mklement0 07
1
Для сравнения find * -maxdepth 0 -type f(альтернатива, полученная из комментария @ AlexHall) с find . -maxdepth 1 -type fответом: find . ...неизменно включает скрытые элементы, неизменно добавляет префиксы к именам выходных файлов с помощью ./, а с GNU find(Linux) обычно выводит несортированный список. find * ..., из-за того, что оболочка позволяет оболочке выполнять подстановку вперед, по умолчанию исключает скрытые элементы (можно изменить с помощью shopt -s dotglob), выводит простые имена файлов (без префикса), отсортированные по алфавиту. Ни один из подходов не включает символические ссылки на файлы; используйте опцию -Lдля этого.
mklement0 07
15
ls -p | grep -v /

ls -p позволяет вам отображать / после имени папки, которое действует как тег, который вы должны удалить.

Dr_Hope
источник
Приятно видеть пример использования lsв дополнение к find, поскольку последний возвращает относительные пути, а первый - только имена файлов. Используйте подходящий инструмент для работы.
Бен Амос
5
  • Функция findanswer ( find . -maxdepth 1 -type f) на основе carlpett работает в принципе, но не совсем то же самое, что и using ls: вы получаете потенциально несортированный список имен файлов, все с префиксом./ , и вы теряете возможность применить lsмногие параметры ;
    также find всегда находит скрытые элементы , тогда как lsповедение 'зависит от наличия или отсутствия опций -aили -A.

    • Улучшение , предложил Алекс Холл в комментариях по этому вопросу, чтобы объединить оболочки подстановки сfind :

          find * -maxdepth 0 -type f  # find -L * ... includes symlinks to files
      
      • Однако, хотя это решает проблему префикса и дает вам вывод , отсортированный в алфавитном порядке , у вас все еще нет ни (встроенного) контроля над включением скрытых элементов, ни доступа ко lsмногим другим параметрам сортировки / формата вывода.
  • Ответ Ханса Роггемана ls+grep прагматичен, но не позволяет использовать -lвыходной формат long ( ) .


Для устранения этих недостатков я написал fls( е iltering Ls ) полезность ,

  • утилита, обеспечивающая гибкость вывода,ls а также возможность фильтрации типов ,
  • просто поместив символы фильтрации типов, такие как fфайлы, dкаталоги и lсимволические ссылки, перед списком lsаргументов (запустить fls --helpили fls --manузнать больше).

Примеры:

fls f        # list all files in current dir.
fls d -tA ~  #  list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)

Установка

Поддерживаемые платформы

  • При установке из реестра npm : Linux и macOS
  • При установке вручную : любая Unix-подобная платформа с Bash

Из реестра npm

Примечание. Даже если вы не используете Node.js, его менеджер пакетов npm, работает на разных платформах и прост в установке; пытаться
curl -L https://git.io/n-install | bash

После установки Node.js установите его следующим образом:

[sudo] npm install fls -g

Примечание :

  • Необходимость sudoзависит от того, как вы установили Node.js / io.js и изменили ли вы разрешения позже ; если вы получите сообщение EACCESоб ошибке, попробуйте еще раз с sudo.

  • -gОбеспечивает глобальную установку и необходимо поставить flsв вашей системе $PATH.

Ручная установка

  • Загрузите этот bashсценарий как fls.
  • Сделайте его исполняемым с помощью chmod +x fls.
  • Переместите его или создайте символическую ссылку в папку в вашем $PATH, например /usr/local/bin(macOS) или /usr/bin(Linux).
mklement0
источник
1
Блестяще. Даже если это предполагает создание другого скрипта. Я скопировал и вставил текстовый источник, на который вы ссылаетесь, в текстовый файл и запустил его в Cygwin с помощью этой команды: fls.sh f * .png> pngs.txt И бинго: список файлов .png без путей. Но в самом деле, ls не имеет опции, сопоставимой с переключателем "dir / b" в DOS? Я просмотрел содержимое вывода ls '--help, и, по крайней мере, ничего подобного там нет.
Alex Hall
1
@AlexHall: Спасибо; tl; dr: попробуйте -1(номер один); lsфактически по умолчанию используется "голый" вывод, то есть только имена файлов, но при выводе на терминал используется макет на основе столбцов (несколько имен файлов в строке). Чтобы получить одно имя файла для каждой строки вывода (что и dir /bимеет значение, если память обслуживает), используйте -1параметр, который фактически неявно включен, когда stdout не подключен к терминалу, например, при отправке в канал или выходной файл.
mklement0
2

Вывод содержимого некоторого каталога без подкаталогов

Мне нравится использовать lsопции, например:

  • -l используйте длинный формат списка
  • -t сортировать по времени модификации, сначала самые новые
  • -r обратный порядок сортировки
  • -F, --classify добавить индикатор (один из * / => @ |) к записям
  • -h, --human-readable с -l и -s, размеры печати, такие как 1K 234M 2G и т. д.

Когда-то --colorи все остальные. (См. ls --help)

Список всего, кроме папок

Это покажет файлы, символические ссылки, устройства, каналы, сокеты и т. Д.

так

find /some/path -maxdepth 1 ! -type d

можно легко отсортировать по дате:

find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +

Только файлы листинга :

или же

find /some/path -maxdepth 1 -type f

отсортировано по размеру:

find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +

Запретить перечисление скрытых записей :

Чтобы не отображать скрытые записи, где имя начинается с точки, вы можете добавить ! -name '.*':

find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +

потом

Вы могли бы заменить /some/pathна .в список для текущего каталога или ..для родительского каталога .

Ф. Хаури
источник
1

Вы также можете использовать lsс grepили egrepи поместить его в свой профиль в качестве псевдонима:

ls -l | egrep -v '^d'
ls -l | grep -v '^d'
Ханс Роггеман
источник
Я бы не стал помещать это в скрипт по указанной выше причине, это другое быстрое и грязное решение: ls -F | grep -v '/ $'
муми
1

найти файлы: ls -l / home | grep "^ -" | тр-с '' | вырезать -d '' -f 9

найти каталоги: ls -l / home | grep "^ d" | тр-с '' | вырезать -d '' -f 9

найти ссылки: ls -l / home | grep "^ l" | тр-с '' | вырезать -d '' -f 9

tr -s '' превращает вывод в файл с разделителями-пробелами, команда cut говорит, что разделитель является пробелом, и возвращает 9-е поле (всегда имя файла / имя каталога / имя ссылки).

Я постоянно этим пользуюсь!

Ричард
источник
Вот Это Да! Что, если имена файлов содержат пробелы?
Ф. Хаури
используйте «9-», чтобы получить все, начиная с 9-го поля. Это также влияет на ссылки, поскольку они будут после 9-го поля.
Ричард
0
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }

добавлен, xargsчтобы заставить его работать, и используется -1вместо того, -lчтобы показывать только имена файлов без дополнительной lsинформации

Анабиоз
источник
В этом есть определенное достоинство, так как он обеспечивает сортировку по времени, хотя есть, возможно, менее неуклюжие способы сделать это сfind -printf0 '...' | sort -z
tripleee
-2

Просто добавляю к ответу Карлпетта. Для более удобного просмотра файлов вы можете передать вывод в ls.

find . -maxdepth 1 -type f|ls -lt|less

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

Абхай
источник
3
Вероятно, это не так, как вы ожидаете! lsне читает стандартный ввод, поэтому передавать что-либо по конвейеру бесполезно ls. Вы пропустили xargs?
gniourf_gniourf
Другими словами: findкоманда в этом ответе полностью игнорируется ; общая команда является таким же , как ls -lt | less, который не выполняет не фильтрации типа.
mklement0 07
1
Хотя с GNU findможно было find . -maxdepth 1 -type f -ls. Она также , кажется, работает на Mac OS, хотя я считаю , -maxdepthи -lsне правильно портативные варианты.
Tripleee
-2

"find '-maxdepth'" не работает с моей старой версией bash, поэтому я использую:

для f в $ (ls); делать, если [-f $ f]; затем echo $ f; fi; сделанный

Джилл Дэвисон
источник
Использование слова for f in $(ls)вдвойне неверно. Вы можете исправить это, for f in *но тогда он сломается, потому что вы echoнеправильно цитируете аргумент .
Tripleee