$ s=/the/path/foo.txt
さまざまな基準で個別に抽出できます。
$ echo ${s##*/}
foo.txt
$ echo ${s%.txt}
/the/path/foo
しかし、同時に2つの基準に基づいて抽出するには
$ echo ${${s##*/}%.txt}
bash: ${${s##*/}%.txt}: bad substitution
一時変数を導入せずにパラメータ拡張だけで同じ目標を達成できますか?
パラメータ拡張は他のパラメータ拡張内で機能できますか?
ありがとうございます。
答え1
もうダメだ。 Bashまたは標準シェルから最初の部分拡張子は次のようになります。範囲(例:変数、位置パラメータ、または特殊パラメータのいずれか)。単なる言葉ではありません。
吹く:
パラメータ拡張の基本形式は$ {範囲}。の価値範囲交換されます。これ範囲上記のように、シェルパラメータまたは配列参照。
これPOSIXのテキストここでもパラメータだけが言及されています。
拡張機能が利用可能その他の部分拡張は任意の単語にすることができます。しかし、これはもちろん同じ文字列への接続操作には役立ちません(あなたの例のように${${s##*/}%.txt}
)。
$ bash -c 's=/the/path/foo.txt; ext=.tyt; echo "${s%${ext/y/x}}"'
/the/path/foo
Zshは明示的にサポートしています。ただし、リンクは次のとおりです。
代わりに ${...} 型パラメーター式または $(...) 型コマンド置換を使用する場合名前上記では、最初に拡張し、結果をまるで拡張したかのように使用します。名前。
答え2
拡張子を持たないファイル名コンポーネント(たとえば)を単一のジョブとして見つける場合は、foo
REマッチングを使用してパスから抽出できます。
s=/the/path/foo.txt
[[ "$s" =~ (.*/)?(.*)\. ]]
echo "Got > ${BASH_REMATCH[2]} <" # "Got > foo <"
複合式を許可しない限り、foo.bar.txt
拡張子がまったくないファイル名コンポーネント(たとえば)を処理しながら、ファイル名から不明な最も短い拡張子を削除する方法が見つかりませんでした。foo
[[ "$s" =~ (.*/)?(.*)(\.[^.]*)$ ]] || [[ "$s" =~ (.*/)?(.*) ]]
これにより、連続して2回の置換を実行してから離れる方が効率的です。
s=/path/to/foo
f=${s##*/}
echo "${f%.*}"