Выводите только полные пути к файлам и каталогам, используя ls

Вопрос или проблема

Для заданного каталога запрос заключается в следующем: необходимо вывести полные пути файлов и каталогов

например, для

      /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

Здесь есть две проблемы:

  1. /a/b/c также будет выведен.
  2. 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-скриптами.

Оцените материал
Добавить комментарий

Капча загружается...