ls: Отображение имени каталога, если только одно соответствует шаблону

ls: Отображение имени каталога, если только одно соответствует шаблону

При использовании lsдля отображения файлов, соответствующих шаблону, он отображает имена каталогов с содержимым, если есть несколько совпадений, но если есть только одно совпадение, он опускает имя каталога. Вот пример:

example % ls
bar     barbados    foo

example % ls b*
bar:
1   2

barbados:
1   2

example % ls f*
1   2

В этом примере запрос всех файлов, начинающихся с, b*соответствует двум каталогам, а в выводе отображаются имена обоих каталогов и их содержимое.

При запросе f*вывод показывает содержимое единственного соответствующего каталога, но опускает имя каталога.

Как настроить lsотображение имени соответствующего каталога в случае, если он соответствует только одному каталогу?

решение1

Возможным решением может стать функция-обертка:

dls() {
    if [ "$#" -eq 1 ] && [ -d "$1" ]; then
        printf '%s:\n' "$1"
    fi
    ls -- "$@"
}
  • Приведенная выше функция не принимает никакие параметры, передаваемые в качестве аргументов.
  • Он просто проверяет:
    1. есть только один аргумент
    2. аргумент — это каталог

Если эти два условия выполняются, выведите имя каталога перед перечислением его содержимого.


% dls f*
foo:
1   2

В некоторых printfреализациях можно заменить %sна %q, чтобы имя каталога было заключено в кавычки аналогично тому, как lsэто делают последние версии GNU, когда оно содержит пробелы или другие специальные символы.

решение2

Используя ваши примеры, когда вы выполняете ls b*, оболочка расширяет b*в bar barbados, так что вы фактически запускаете ls bar barbados. Когда lsимеет несколько аргументов, если какой-либо из них является каталогом, он печатает имя, за которым следует список файлов в каталоге.

Когда вы выполняете ls f*, то shell расширяет f*в foo, так что вы фактически запускаете ls foo. Когда lsимеет один аргумент, если этот аргумент является каталогом, выводит список файлов в каталоге (без имени каталога).

Нет того, что я бы назвал "хорошим" способом сделать lsто, что вы хотите (по крайней мере, я о таком не знаю, кто-то другой может знать лучше). Один "менее хороший" способ - включить дополнительный аргумент, который, как вы знаете, никогда не будет существовать, а затем отфильтровать вывод ошибок, связанных с этим несуществующим файлом. Я отмечу для протокола, что парсинг вывода ls- плохая идея, но я дам вам это на всякий случай:

$ function dls() {
    if [[ $# -eq 0 ]]; then
        ls
    else
        ls ${@} this-file-does-not-exist-anywhere 2> >(grep -v this-file-does-not-exist-anywhere)
    fi
}

$ dls
foo

$ dls f*
foo:
1  2

Подобные действия могут иметь непредвиденные последствия (например, вы не сможете перенаправлять стандартные сообщения об ошибках, как обычно).

решение3

Используйте -alпараметр, который большинство людей используют каждый раз. lsне будет делать этого тогда, пока вы не добавите завершающий слеш к имени каталога. Другой параметр - это -d, он не будет спускаться никаким образом, тогда.

Если вы хотите, чтобы он был постоянным, поместите следующее в .bashrcсвой домашний каталог:

alias lsd='ls -d' ;

Эту команду вы сможете использовать lsdв будущем.

Связанный контент