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
使用すると、リンク名のみが出力され、参照先の権限を取得できます(良い点です)。オプションのリンク参照を解除しましたが、リンクが実際に接続であるかどうかを知る方法はありません。-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
答え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つのファイル形式を別々に個別に処理するのが便利です。その場合は、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).
上記のコマンドを単一のコマンドに結合することもできます(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
で-mindepth
GNU拡張なので、この方法はGNUでのみ機能しますfind
。
以下は、問題のあまり具体的ではない最初のバージョンのソリューションとして公開されています。他の人に役立つ可能性があるので、ここに残しておきます。
シェルと
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
。これがあなただけのためであり、解析する意図がない場合は、次のものを使用してください
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
。