Вопрос или проблема
Для заданного каталога запрос заключается в следующем: необходимо вывести полные пути файлов и каталогов
например, для
/a/b/c/
file1
file2
dir1/
Команда должна показать
/a/b/c/file1
/a/b/c/file2
/a/b/c/dir1
Форма команды будет либо
ls -<что-то> .
или
ls -<что-то> /a/b/c
Я думал, что это будет легко сделать, но не нашел такого, просмотрев все переключатели ls
. Может, я что-то упустил? Или нужно использовать что-то другое, например find
?
find
может выдать нужный формат почти по умолчанию. Он обязан использовать имена путей, начинающиеся с указанного вами пути, поэтому укажите /a/b/c
:
find /a/b/c
что эквивалентно
find /a/b/c -print
Здесь есть две проблемы:
/a/b/c
также будет выведен.find
работает рекурсивно. Неясно, является лиdir1
в вашем примере пустым или его содержимое опускается. Возможно, вам не нужна рекурсия.
Проблема может быть решена с помощью -mindepth 1
и -maxdepth 1
, если ваша версия find
их поддерживает:
find /a/b/c -mindepth 1 -maxdepth 1
Эти опции не обязательны по стандарту POSIX. С POSIX find
вы можете подавить вывод /a/b/c
с помощью ! -path /a/b/c
; и вы можете “эмулировать” -maxdepth 1
, следуя этому: Ограничить POSIX find до конкретной глубины?
Это решение для POSIX:
find /a/b/c ! -path /a/b/c -prune
Один лишь /a/b/c
не пройдет тест ! -path
. Все, что пройдет, будет отсечено, так что инструмент не будет углубляться дальше.
Если вы указываете начальный путь как /a/b/c/
(обратите внимание на завершающий слэш), вам нужно использовать ! -path /a/b/c/
(тоже с завершающим слэшем), потому что find
обязан уточнять начальный путь точно так, как он был указан. /a/b/c/
не совпадает с /a/b/c
и наоборот. Помните, что -path
рассматривает свой аргумент как шаблон, это важно, если ваш начальный путь содержит литеральные *
или другие символы, используемые в Обозначение шаблонов соответствия.
Вы запросили конкретный формат, поэтому, возможно, хотите анализировать вывод. В таком случае find
— ваш инструмент, а ls
точно нет, потому что не стоит парсить вывод ls
. Если ваш find
— это GNU find
, ознакомьтесь с разделом НЕОБЫЧНЫЕ ИМЕНА ФАЙЛОВ
в man 1 find
. Рассмотрите -print0
.
В комментарии вам дали ссылку на этот вопрос. Многие решения там требуют подстановки пути какому-то инструменту (например, readlink
). Если исходный путь поступает из ls
, это уже является актом “парсинга ls
” – не рекомендуется.
Однако инструменты из этого другого вопроса могут быть полезны в вашем случае, чтобы превратить относительный путь, как ./c
или c
, в полный путь, как /a/b/c
. Тогда вы предоставляете полный путь find
.
DIR_PATH="./" ; readlink -f $(ls -1 ${DIR_PATH})
Команда find
медленнее.
Ответ или решение
Для решения задачи по выводу полных путей файлов и директорий в заданной директории при использовании команды ls
, необходимо учитывать, что ls
изначально не предоставляет функциональности для отображения полных путей. Однако, для решения этой задачи можно использовать комбинацию команд или прибегнуть к помощи других утилит, таких как find
.
Теория
Команда ls
используется для отображения содержимого директории в консоли. Она поддерживает множество параметров и опций, которые позволяют изменять формат вывода, однако она в первую очередь предназначена для вывода названий файлов и директорий, а не абсолютных путей. При этом ls
имеет опции, которые позволяют получать подробную информацию о файлах, как то: -l
, -a
, -r
, и т.д. Использование опции -d
изменяет поведение команды так, чтобы она показывала только директорию, а не её содержимое. Однако, ни один из этих флагов не позволяет напрямую выводить абсолютные пути объектов в директории.
Поэтому целесообразно рассмотреть использование команды find
, которая специально предназначена для поиска и вывода путей объектов в файловой системе. Она обладает множеством параметров, включая -mindepth
и -maxdepth
, которые позволяют контролировать уровень рекурсии при поиске.
Пример
Предположим, у вас есть структура директории следующего вида:
/a/b/c/
file1
file2
dir1/
Цель — вывести полные пути всех файлов и директорий внутри /a/b/c
, без рекурсивного перечисления вложенного содержимого.
Использование команды find
Для вывода только содержимого директории /a/b/c
без рекурсивного поиска можно использовать команду find
с параметрами -mindepth 1
и -maxdepth 1
, которая предотвращает спуск в поддиректории:
find /a/b/c -mindepth 1 -maxdepth 1
Это даст вам следующий вывод:
/a/b/c/file1
/a/b/c/file2
/a/b/c/dir1
Данная команда будет выводить только элементы, находящиеся непосредственно в указанной директории, исключая саму директорию /a/b/c
и не спускаясь в её поддиректории, что соответствует вашей потребности.
Применение
В реальной работе, использование команды find
вместо ls
является более предпочтительным, если вашей задачей является обработка или парсинг полного путя. Синтаксис find
позволяет гибко управлять выводом и поддерживает расширенные возможности фильтрации.
Для удобства использования, особенно в сценариях с динамически изменяемыми путями, можно создовать скрипты или воспользоваться встроенными в UNIX средствами, такими как использование readlink
для преобразования относительных путей, если это необходимо.
Бонусом использования find
является его надёжность при работе с необычными именами файлов, включая те, которые содержат специальные символы или пробелы. В отличие от ls
, его можно безопасно использовать в сценариях автоматизации или в цепочках команд, минимизируя риск ошибок, связанных с неправильно обработанными именами файлов.
Таким образом, для реализации задачи вывода полных путей файлов в конкретной директории рекомендуется использовать команду find
, что предоставляет более гибкий и надёжный подход. Совмещение команд readlink
и find
также может быть полезным, когда требуется преобразовать относительные пути в абсолютные в сценариях с bash-скриптами.