LSコマンドを使用してディレクトリを一覧表示するときのファイル形式と逆参照

LSコマンドを使用してディレクトリを一覧表示するときのファイル形式と逆参照

lsディレクトリの内容を一覧表示するためにコマンドのパラメータを結合しようとしています。私が基本的に達成しようとしているのは、すべてのリンクを逆参照するディレクトリをリストしますが、リストされたエントリがリンクであることを明確に表示することです。--dereferenceとオプションを結合しようとしましたが、リンク先が実行可能ファイルであるため、--classifyリンク記号()の代わりに表示されます@*

どのようにこれらの結果を得ることができるかについてのアイデアはありますか?lsコマンド以外のオプションも開いています。

編集する: 実際にはコマンドで他のオプションを使用しましたls。私の現在のコマンドとそのオプションは次のとおりです。

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

->構築中のアプリケーション内で出力を解析しようとしていますが、矢印()を持つデフォルトのリンク出力は使用できません。フォルダ、ファイルなど、ディレクトリの他のエントリも一覧表示する必要があります。

編集(2):

明確にするために、SSH2 APIを使用してサーバーに接続し、ディレクトリを一覧表示するJavaアプリケーションを開発しています。リストの結果は、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使用すると、リンク名のみが出力され、参照先の権限を取得できます(良い点です)。オプションのリンク参照を解除しましたが、リンクが実際に接続であるかどうかを知る方法はありません。-Lls-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

答え1

更新された質問に応じて編集されました

リンク、ディレクトリ、および一般ファイルにのみ関心があり、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ファイル名が含まれます。これらのファイルのほとんどはlsメソッドを破壊しますが、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に似ていますが、バックスラッシュエスケープが解釈され、強制的に末尾の改行は出力されません。改行文字が必要な場合は、FORMATに\ 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

あるいは、ファイル形式を解析するだけです。


実行する操作によっては、検索している3つのファイル形式を別々に個別に処理するのが便利です。その場合は、find1とその-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).

上記のコマンドを単一のコマンドに結合することもできます(find演算子を使用する)が、ファイルの種類に応じて任意の文字列を印刷-oできます。-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ただし、改行文字を含むファイル名を適切に処理するには、構文解析時に注意するか(「line」が始まるかどうかを確認する[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-mindepthGNU拡張なので、この方法はGNUでのみ機能しますfind


以下は、問題のあまり具体的ではない最初のバージョンのソリューションとして公開されています。他の人に役立つ可能性があるので、ここに残しておきます。

  1. シェルと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場合)、それを逆参照します(次の点に注意してください。$freadlink -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

関連情報