Тип файла и разыменование при указании каталога с помощью команды LS

Я пытаюсь объединить аргументы в команду ls чтобы отобразить содержимое каталога. То, что я в основном пытаюсь достичь, – это листинг каталога, разыменовывающий все ссылки, но явно показывающий, что указанный элемент является ссылкой. Я попытался объединить параметры --dereference и --classify , но вместо отображения символа ссылки ( @ ) я получаю * поскольку ссылка нацелена на исполняемый файл.

Любые мысли о том, как я могу получить такой результат? Я открыт для альтернатив, кроме команды ls .

EDIT: Я использую другие опции из команды ls . Моя текущая команда вместе со своими опциями – это один ниже:

 ls -ogq -LB --group-directories-first --time-style=long-iso 

Я намерен анализировать вывод внутри приложения, которое я создаю, и не могу использовать вывод ссылки по умолчанию со стрелкой ( -> ). Также должны быть указаны другие элементы в каталоге (например, папки и файлы).

EDIT (2):

Чтобы уточнить, я разрабатываю Java-приложение, которое использует SSH2 API для подключения к серверам и спискам каталогов. Результат из списка затем используется для заполнения дерева с помощью jsTree jQuery-плагина. В настоящее время команда, приведенная выше, дает мне следующий результат:

 felipe@simba:/mnt/drive$ ls -ogq --group-directories-first --time-style=long-iso total 12 drwxr-sr-x 2 4096 2014-06-11 18:04 folder1 drwxr-sr-x 6 4096 2014-06-27 19:35 folder2 dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions -rw-r--r-- 1 0 2014-06-30 10:42 file.txt lrwxrwxrwx 1 49 2014-06-30 11:36 linkTeste -> folder2/dir/otherfile.txt 

Применяя регулярное выражение, я могу определить, что такое папка, файл или ссылка, просмотрев разрешения. Но когда у меня есть ссылка, мне нужно указать только имя ссылки, а не name -> destination . Если я использую параметр -L для команды ls выводится только имя ссылки, и я получаю разрешения назначенного адресата (что хорошо), поскольку опция -L разделяет ссылку, но таким образом я не могу знать, что ссылка на самом деле является ссылкой.

 felipe@simba:/mnt/drive$ ls -ogq -L --group-directories-first --time-style=long-iso total 12 drwxr-sr-x 2 4096 2014-06-11 18:04 folder1 drwxr-sr-x 6 4096 2014-06-27 19:35 folder2 dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions -rw-r--r-- 1 0 2014-06-30 10:42 file.txt -rwxr-xr-x 1 0 2014-06-27 18:40 linkTeste 

Мне нужно указать только имя ссылки, знать, что это ссылка, и знать, что такое пункт назначения (файл, папка или ссылка). Я могу обрабатывать различные виды вывода, так как в любом случае я буду применять регулярное выражение.

Также приветствуются альтернативы, использующие find или stat .

One Solution collect form web for “Тип файла и разыменование при указании каталога с помощью команды LS”

Изменить в ответ на обновленный вопрос

Поскольку вам все равно, только ссылки, каталоги и обычные файлы, и вам не нужно иметь дело с другими типами файлов, которые могут идентифицироваться (FIFO, сокеты и т. Д.), Вы можете сделать что-то вроде stat . В приведенных ниже примерах я создал следующую тестовую среду:

 $ ls -l total 4.0K -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a new?line -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a space -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a?tab drwxr-xr-x 2 terdon terdon 4.0K Jun 30 23:11 dir1 lrwxrwxrwx 1 terdon terdon 4 Jun 30 23:13 linktodir1 -> dir1 lrwxrwxrwx 1 terdon terdon 7 Jun 30 23:13 sh -> /bin/sh 

Как вы можете видеть, это ссылки, ссылки на исполняемые файлы, имя файла с пробелом, одно с вкладкой ( \t ) и одно с новой строкой ( \n ). Большинство из этих файлов нарушат ваш подход, но stat может справиться с ними правильно:

 $ stat --printf "%A\t%N\t%F\n" * -rw-r--r-- 'a new\nline' regular file -rw-r--r-- 'a space' regular file -rw-r--r-- 'a\ttab' regular file drwxr-xr-x 'dir1' directory lrwxrwxrwx 'linktodir1' -> 'dir1' symbolic link lrwxrwxrwx 'sh' -> '/bin/sh' symbolic link 

Соответствующие разделы man stat :

–printf = ФОРМАТ

например, –format, но интерпретировать escape-обратные сбрасывания и не выводить обязательную конечную новую строку. Если вы хотите новую строку, укажите \ n в ФОРМАТЕ

% Права доступа в удобочитаемой форме

% F тип файла

% N цитированное имя файла с разыменованием, если символическая ссылка

Обратите внимание, что поля разделяются символом \t , это означает, что вы сможете обрабатывать пробелы внутри полей (например, в именах файлов).

Вы упомянули, что не можете иметь дело -> . Я не совсем понимаю, почему, но вы можете либо просто удалить это с помощью sed

 $ stat --printf "%A\t%N\t%F\n" * | sed 's/->//' lrwxrwxrwx 'linktodir1' 'dir1' symbolic link 

или заменить его другой строкой:

 $ stat --printf "%A\t%N\t%F\n" * | sed 's/->/→/' | grep linktodir lrwxrwxrwx 'linktodir1' → 'dir1' symbolic link 

или просто проанализировать тип файла.


В зависимости от того, что вы хотите сделать, может быть полезно разделить каждый из трех типов файлов, которые вы ищете, и обрабатывать их по отдельности. Если это так, используйте -printf find 1 и ее -printf :

 $ find ./ -maxdepth 1 -mindepth 1 -type f -printf '%M\t%P\t%l\n' ## files $ find ./ -maxdepth 1 -mindepth 1 -type d -printf '%M\t%P\t%l\n' ## directories $ find ./ -maxdepth 1 -mindepth 1 -type l -printf '%M\t%P\t%l\n' ## links 

В этом случае директивы printf

  %M File's permissions (in symbolic form, as for ls). This directive is supported in findutils 4.2.5 and later. %P File's name with the name of the command line argument under which it was found removed. %l Object of symbolic link (empty string if file is not a symbolic link). 

Вы также можете объединить приведенное выше в одну команду (используя оператор -o find ), но который позволяет использовать -printf для печати произвольной строки в зависимости от типа файла. Например:

 $ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\n' \) \ -o \( -type d -printf 'dir:\t%M\t%P\n' \) \ -o \( -type f -printf 'file:\t%M\t%P\n' \) file: -rw-r--r-- a?tab file: -rw-r--r-- a space link: lrwxrwxrwx linktodir1 dir1 file: -rw-r--r-- a new?line dir: drwxr-xr-x dir1 link: lrwxrwxrwx sh /bin/sh 

Приведенная выше команда будет правильно интерпретировать \t и \n если ее вывод не отображается на терминале. Однако, чтобы правильно обрабатывать имена файлов с новыми символами, вам нужно быть осторожными при разборе (убедитесь, что «строка» начинается с [file|dir|link]: или используйте \0 в качестве ограничителя строки в каждом вызове printf вместо \n :

 $ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\0' \) \ -o \( -type d -printf 'dir:\t%M\t%P\0' \) \ -o \( -type f -printf 'file:\t%M\t%P\0' \) 

1 -maxdepth и -mindepth являются расширениями GNU, поэтому этот подход будет работать только для find GNU.


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

  1. Shell и readlink

     for f in *; do readlink "$f" >/dev/null && echo "$(readlink -f "$f") (link)" || echo "$f"; done 

    Пример вывода:

     /etc (link) foo sample.R sample.R~ 

    Вышеупомянутый повторяет все файлы и каталоги под текущим, и если readlink возвращает успешное (если $f является ссылкой), он будет разыменовывать его ( readlink -f , обратите внимание, что это будет следовать за всеми ссылками. Если вы хотите только первый уровень , удалите -f ) и распечатайте цель вместе с (link) . Если это не так, он просто напечатает $f .

  2. Если это только для вас и не предназначено для анализа, просто используйте ls -l :

     $ ls -l total 512116 -rw-r--r-- 1 terdon terdon 100641 Jun 30 19:10 er lrwxrwxrwx 1 terdon terdon 5 Jun 30 19:12 etc -> /etc/ -rw-r--r-- 1 terdon terdon 524288000 Jun 30 19:10 foo -rwxr--r-- 1 terdon terdon 353 Jun 30 15:22 sample.R -rwxr--r-- 1 terdon terdon 249 Jun 30 14:51 sample.R~ 

    Это ясно укажет на ссылки со link -> target .

  • Что-то вроде символически связанного файла, но с привязанными данными изменения?
  • Как вы можете группировать символические ссылки с каталогами в выводе `ls`, но сказать разницу?
  • Где хранится информация о жестких / непрямых ссылках?
  • Файловая система Docker - совместимость с символическими ссылками
  • Как эта символьная связь не следует следовать?
  • Что произойдет, если случайно переместить мягкую ссылку, а затем «/»?
  • Debian: Как разрешить ошибку перемещения?
  • Как предупредить sed -i от уничтожения символических ссылок?
  • В Ubuntu есть ли способ практически объединить две папки без unionfs или aufs?
  • ls в каталоге, игнорирующем символические ссылки
  • можете ли вы добавить псевдоним в позицию внутри файла?
  • Linux и Unix - лучшая ОС в мире.