Bashのパス名のパターンマッチング

Bashのパス名のパターンマッチング

ディレクトリ内のサブディレクトリのリストを操作したいと思います。考慮する:

for x in x86-headers/*/C/populate.sh; do echo $x; done

これは

x86-headers/elf/C/populate.sh
x86-headers/gl/C/populate.sh
x86-headers/gmp/C/populate.sh
x86-headers/gnome2/C/populate.sh
x86-headers/gtk2/C/populate.sh
x86-headers/jni/C/populate.sh
x86-headers/libc/C/populate.sh

ただし、パスの2番目の部分などに対応する値が必要ですelfgl私は先行を削除する方法を知っていますx86-headers

for x in x86-headers/*/C/populate.sh; do i=${x##x86-headers/}; echo $i; done

これは作る

elf/C/populate.sh
gl/C/populate.sh
gmp/C/populate.sh
gnome2/C/populate.sh
gtk2/C/populate.sh
jni/C/populate.sh
libc/C/populate.sh

また、パスから後続の用語を削除する方法も知っています。つまり、1つのレベルを下げます。

cd x86-headers
for x in */C/populate.sh; do i=${x%%/*}; echo $i; done

与えられた

elf
gl
gmp
gnome2
gtk2
jni
libc

ただし、これらを組み合わせようとすると機能しません。つまり

for x in x86-headers/*/C/populate.sh; do i=${${x##x86-headers}%%/*}; echo $i; done

与えられた

bash: ${${x##x86-headers}%%/*}: bad substitution

疑いなく、これは間違った構文ですが、正しい構文を知りません。もちろん、これより良い方法があるかもしれません。 Pythonを使用している場合は、分割を使用して/各パスをリストに分割して2番目の要素を選択しますが、bashでこれを行う方法がわかりません。

編集:答えてくれてありがとう。また、この移植性が可能なのか、それならどうすることができるのか尋ねなければなりません。

ベストアンサー1

(またはPOSIXly)と組み合わせることはできず、bash2つのステップで行う必要があります。

i=${x#*/}; i=${i%%/*}

すべてのPOSIXシェルに移植可能です。 Bourne Shellの移植性が必要な場合(ただし、質問にタグを付けるのはなぜですか?)/強く打つだから? )Solarisに移植し、その/bin/sh標準を強制的に使用するsh場合、または20年前のシステムに移植する場合は、この方法を使用できます(この方法はPOSIXシェルでも機能します):

IFS=/; set -f
set x $x
i=$3

(上記の場合は、変数を引用符で囲んでいないままにすることが意味のあるまれな場合の1つです。)

記録にzshを使用します。

print -rl -- x86-headers/*/C/populate.sh(:h:h:t)

(これティーみんな時間時間ファイルの先頭)。

またはあなたのpython方法に応じて:

x=elf/C/populate.sh
i=${${(s:/:)x}[2]}

おすすめ記事