4

では、次の唯一のサブフォルダーの名前を取得したいと思いますa

cd /tmp; mkdir -p a/b; v=$(ls -1 a); echo "$v"

出力:

b

それが私が欲しかったものです。

内に唯一のサブフォルダーがあることがわかっているため、これは機能しますa

私のシナリオでは、すべてのケースでこれが保証されていると思い込んでください。

私が不安に思っているのは、Bashの落とし穴からのこの推奨事項です

In addition to this, the use of ls is just plain unnecessary.
It's an external command whose output is intended specifically
to be read by a human, not parsed by a script.

これはさらに威圧的で宝石商です(上記と同じリンクから):


ls の出力の解析 -- 出力を決して解析してはならないユーティリティ。


それは私に共鳴しますが、これはグロビングを使用する試みです。動作しません:

 cd /tmp; mkdir -p a/b; v=a/*; echo "$v"

出力:

a/*

悲しみ。

では、変数代入のグロビングを取得するにはどうすればよいでしょうか?

割り当ての外でグロビングを活用する方法を知っていると思います..

for d in a/*; do echo "$(basename $d)"; done

出力:

b

「正解」(TM)。

これを正しく行う方法と、その背後にある原理も説明してください。

** 注: このコマンドの出力は好きではありません:**

cd /tmp; w='name with blanks'; mkdir -p "$w/b"; v=$(echo "$w"/*); echo "$v"

つまり:

name with blanks/b

私はちょうど取得したい:

b

後で使用する必要がありますか、それとも直接取得できますか?basenameb

4

2 に答える 2

4

その落とし穴の文を書いたのは確かです。とにかく...ブレース展開、グロブ、および単語分割はスカラー代入に適用されないため、あなたのものは失敗します。

printf -v v %s */

そして、coreutils を使用した場合にのみ機能するあまり知られていないトリックprintf(1)(複数のディレクトリがあると仮定)。

v=$(LC_COLLATE=C; /usr/bin/printf '%s\c' */)

または、これはおそらくあなたが求めているものに最も近いものです(GNU find):

v=$(find . -maxdepth 1 -type d -name '[^.]?*' -printf %f -quit)

参照: http://mywiki.wooledge.org/ParsingLs

于 2013-04-04T11:55:03.610 に答える
4
v=$(cd a;echo *)

ワイルドカードはコマンド置換内で展開され、echo出力されるため、割り当てで使用されます。

を使用cdすると、 を呼び出さずにベース名を取得できますbasename

于 2013-04-04T03:05:11.707 に答える