`ls`を使用してソースファイルとターゲットリンクファイルのみを表示する


11

リンクが使用するターゲットファイルを使用して表示できますls -l

snowch$ ls -l /usr/local/bin/mvn
lrwxr-xr-x  1 snowch  admin  29 12 Dec 08:58 /usr/local/bin/mvn -> ../Cellar/maven/3.2.3/bin/mvn

awkなどの別のコマンドをパイプすることなく、出力を少なくする方法はありますか?例えば:

snowch$ ls ?? /usr/local/bin/mvn
/usr/local/bin/mvn -> ../Cellar/maven/3.2.3/bin/mvn

OS X 10.9.5で3.2.53を実行しています。いくつかのコマンドの出力を以下に示します。

snowch$ ls -H /usr/local/bin/mvn
/usr/local/bin/mvn

snowch$ ls -L /usr/local/bin/mvn
/usr/local/bin/mvn

snowch$ file /usr/local/bin/mvn
/usr/local/bin/mvn: POSIX shell script text executable

snowch$ file -b /usr/local/bin/mvn
POSIX shell script text executable

回答:


7

ls残念ながら、ファイル属性を取得して任意の方法で表示するオプションはありません。一部のシステムには、そのための個別のコマンドがあります(たとえば、GNUにはGNUのstatコマンドまたは機能がありますfind)。

ただし、ほとんどのファイルを使用する最新のシステムでは、これでうまくいくはずです。

$ ln -s '/foo/bar -> baz' the-file
$ LC_ALL=C ls -ldn the-file | sed '
   1s/^\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{8\}//'
the-file -> /foo/bar -> baz

これは、の出力の最初の行の最初の8つの空白区切りフィールドを削除することで機能しls -lます。これは、gidが表示されないシステム、またはリンクが多数ある場合に最初の2つのフィールドが結合されるシステムを除いて機能します。

GNUの場合stat

$ LC_ALL=C stat -c '%N' the-file
'the-file' -> '/foo/bar -> baz'

GNUの場合find

$ find the-file -prune \( -type l -printf '%p -> %l\n' -o -printf '%p\n' \)
the-file -> /foo/bar -> baz

FreeBSD / OS / X statの場合:

f=the-file
if [ -L "$f" ]; then
  stat -f "%N -> %Y" -- "$f"
else
  printf '%s\n' "$f"
fi

zshSTAT:

zmodload zsh/stat
f=the-file
zstat -LH s -- "$f"
printf '%s\n' ${s[link]:-$f}

多くのシステムには、readlink特にリンクのターゲットを取得するコマンドもあります。

f=the-file
if [ -L "$f" ]; then
  printf '%s -> ' "$f"
  readlink -- "$f"
else
  printf '%s\n' "$f"
fi

stat -f "%N -> %Y" -- /usr/local/bin/mvnうまくいきました。ありがとう!
クリススノー

1
古いRHEL6システムでは、statはGNU coreutils 8.4であり、そこにありstat -c %N -- /usr/local/bin/mvnます。引用を削除するには、これをパイプに入れなければなり| perl -pe 's/['"'"'`]//g'
ませんでした

@cfi tr -d \'\`で十分です。RHELシステムにはGNU findがあり、それを使用してより詳細に制御できることに注意してください。
ステファンChazelas

5

fileコマンドを使用します。

[sreeraj@server ~]$ ls -l mytest
lrwxrwxrwx 1 sreeraj sreeraj 15 Dec 12 09:31 mytest -> /usr/sbin/httpd

[sreeraj@server ~]$ file mytest
mytest: symbolic link to `/usr/sbin/httpd'

または

[sreeraj@server ~]$ file -b mytest
symbolic link to `/usr/sbin/httpd'
[sreeraj@server ~]$

また、のmanページを読みls、オプション-Lをチェックして、-Hそれで十分かどうかを確認してください。


クールで毎日新しいことを学びましょう。
rob

@スリー-どうもありがとう!私はlsオプションを試しましたが、しませんでしたfile。残念ながら、どちらも機能していないようです:(
Chris Snow

@SHC申し訳ありませんが、私はあなたがlinux箱の上にいると思いました。osxタグの1つとして追加してください。それosxもユーザーの注意を引くはずです。投稿を編集してタグを追加しましたが、編集内容をすぐに表示するのに十分なクレジットがありません。
2014

@Sree-ご心配なく、混乱してごめんなさい。Linuxマシンに戻ったときに役立つので、とにかくあなたの答えを賛成しました。
クリススノー

おそらく、OSXの「readlink」ユーティリティを確認してください。
tonioc 14

2

ls少なくともGNU (および、明らかにtcshの実装)を使用すると、$LS_COLORS環境変数をハックして区切り文字を好きな場所に挿入できます(ただし、tcsh'ビルトインls-Fはリンクターゲットを実行せず、リンクフラグのみを実行します通常ls、印刷不可能な任意のターミナルエスケープを挿入しますその環境変数内に格納されている値に基づいていますが、代わりに任意のものを挿入することを妨げるものはありません。詳細はこちら

例えば:

LS_COLORS='ln=///\n:lc=:no=//:rc=:rs=:' \
\ls ~ -l --color=always | 
sed '\|///|,\|//|!d;//d'

これは、//すべてのリストの先頭(の直前lrwcrwx///\nリンクのファイル名の直前に文字列を配置します。sed次に、行範囲でフィルタリングします。dすべての入力行が検出されるまで削除さ///れ、そこから一致する次の行まで一致//する行が削除されます//。したがって、介在する文字に関係なく、リンク名とリンクターゲットのみを取得します。これは/、ファイル名では発生できないためlsです。また、パスに含まれるものは印刷される可能性があるため、単独で発生します。

見る?

mkdir test; cd test
touch 'long


name' shortname
ln -s l* "$(printf %s.ln l*)"; ln -s s* shortname.ln

LS_COLORS='ln=///\n:lc=:no=//:rc=:rs=:' \
\ls  -l --color=always | sed '\|///|,\|//|!d;//d'

...印刷:

long


name.ln -> long


name
shortname.ln -> shortname

自分で試してみてください。


その方法lsをサポートLS_COLORSするGNUの最新バージョン以外の実装と、--color=always引数の後にオプションを知っていますか?GNUシステムの場合は、なぜあなたは、あなたが使用することができたときに回旋ものを使用しますfindstat?また、いくつかを実行しても機能しない可能性がありますln -s /// some-file
ステファンChazelas

@StephaneChezales- これは、少なくともbsdと同様に機能することを示しlsます。数か月前のどこかで、lssが構文のようなtermcapを受け入れる傾向があることについて、どこかで読んだことを覚えています。ln -s ///事の良い点-NUL \0も同様に- -R再帰的に。理由について-まあ、それは使いやすいです。場合によっては、より簡単な場合もfindありますが、ここでfindは、トピックよりも少し話題になっているように見えました。いずれにせよ、あまり多くの人がそれを検討しているわけではないので、気が付いたときに言及します。
mikeserv 2014

FreeBSD については、manページまたはそちらを参照してください。FreeBSDでテストしたい場合は、VMでGhostBSD / mfsbsdなどのライブCDを使用できます。
ステファンChazelas

@StéphaneChazelas-いいえ、私はそれをテストする必要はありません- 完全に別の動物です。あなたが気にしたい場合は、GNUソースもこの回答のリンクにリンクされています。他にどこで読んだのかな?それを指摘してくれてありがとう、それは私が捨てて喜んでいる誤った仮定でした。私は答えを編集しました。
mikeserv 14

最近のバージョンのにtcshは、一部のバージョンのGNUと同じ方法ls-Fをサポートするビルトインがありますが、オプションを渡した場合は呼び出しに頼るので、システム上のGNU でない限り、ここでは機能しません。LS_COLORSlsls -Flsls
ステファンChazelas

-1

[Linux / Bashの場合]

私はこれを行います:

ls -l | sed -e"s/ \+/ /g" | cut -d' ' -f 9-

このsedコマンドは、複数のスペースを1つのスペースに折りたたみます。cutフィールド・セパレータはスペースです以降第九フィールドを抽出します。

これからの典型的な出力:

libboost_atomic.a
libboost_atomic.so -> libboost_atomic.so.1.57.0
libboost_atomic.so.1.57.0
...
libboost_wserialization.a
libboost_wserialization.so -> libboost_wserialization.so.1.57.0
libboost_wserialization.so.1.57.0

代替案は次のとおりです。

ls -l | awk '{ print $9, $10, $11 }'
ls -l | awk '{ $1 = $2 = $3 = $4 = $5 = $6 = $7 = $8 = "" ; print }'

しかし、これらは不完全です。最初のコードは末尾のスペースを出力できます。2番目の先行スペース。


質問は、「...別のコマンドを介してパイプする必要がない...」
ジェフシャラー

@JeffSchaller:良い点。同意する。ただし、これは、タイトルの質問への回答を希望する人にとって(説明の詳細なしで)引き続き役立つことを願っています。
Rhubbarb 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.