У меня есть определенный порядок файлов, которые я хочу перечислить, если они существуют; около 40 файлов. Какой-то приоритет. Итак, я попробовал:
ls -1d /opt/foo/lib.jar /opt/bar/lib.jar
Я ожидал, что это сначала перечислит /opt/foo/lib.jar
если оба существуют. Но на самом деле он сначала печатает bar
а потом – foo
.
Есть ли способ заставить ls
перечислять записи в порядке, указанном в параметрах?
Или какой-то альтернативный подход с find
?
С GNU ls
вы можете попробовать опцию -U
:
-U
: не сортировать; список записей в порядке каталога
(хотя здесь мы не перечисляем содержимое каталогов, поэтому важная часть не сортируется ).
$ ls -1dU /opt/foo/lib.jar /opt/bar/lib.jar /opt/foo/lib.jar /opt/bar/lib.jar
Чуть более переносимый (работает с GNU и FreeBSD ls
, но не с традиционными реализациями ls
и не является POSIX), вы можете использовать ls -1df
:
$ ls -1df /opt/foo/lib.jar /opt/bar/lib.jar /opt/foo/lib.jar /opt/bar/lib.jar
После упоминания find
я обнаружил, что в качестве аргумента пути может быть использовано более 1 пути. Так просто
find /opt/foo/lib.jar /opt/bar/lib.jar -prune 2> /dev/null
Вы можете создать функцию-обертку вокруг ls
которая перебирает аргументы (в порядке их появления), вызывая ls
для каждого:
myls() { for arg do ls -d -- "$arg" done }
Со ссылкой на ответ Стефана в разделе Как использовать аргументы типа $ 1 $ 2 … в цикле for? для синтаксиса for arg do
.
В zsh
, чтобы свести список файлов к существующим, вы можете использовать (N)
квалификатор glob, добавленный к каждому элементу списка:
files=(/opt/foo/lib.jar /opt/bar/lib.jar) that_exist=($^files(N)) (($#that_exist > 0 )) && print -rl -- $that_exist
Обратите внимание, что в отличие от ls
, он может сказать, существует ли файл или нет, даже если у вас нет доступа к поиску в его родительском каталоге (если у вас все еще есть доступ для чтения), поскольку он ищет соответствующие записи в каталоге, не пытаясь чтобы получить доступ к файлу.
Смотрите также:
that_exist_after_symlink_resolution=($^files(N-^@))
Который выбирает файлы, которые не являются ( ^
) символической ссылкой ( @
) после разрешения символической ссылки ( -
). Эквивалент использования ls -Ld
.
Если у вас есть список путей, которые вы хотели бы просмотреть и проверить на существование, то я предполагаю, что вы хотели бы либо сделать что-то из существующих, для тех, которые не существуют, либо для оба набора путей.
Учитывая стандартную оболочку, это лучше всего сделать в цикле.
for pathname in /the/first/path /the/second/path /some/other/path do if [ -e "$pathname" ]; then printf 'Path "%s" exists\n' "$pathname" else printf 'Path "%s" does not exist\n' "$pathname" fi done