
以下のように変数に文字列があるとしましょう。
var="/fnxn/ngfdg/abc.ext"
次のように、この変数のルート(拡張子.*削除)を取得できます。
echo ${var%.*}
次のように、この変数の尾(パスを削除* /)を取得できます。
echo ${var##*/}
ただし、パスと拡張子を削除する必要があります。次のように、異なる変数を使用して2つのステップで実行できます。
var2=${var##*/}
var3=${var2%.*}
ただし、シングルステップオプション(以下のzsh構文に似ています)は、bashの「Bad Substitution」エラーメッセージを表示します。
echo ${${var##*/}%.*}
コードの長さを減らし、追加の環境変数を防ぐための理解可能なシングルステップオプションがあれば便利です。
答え1
固定された拡張子がある場合POSIXbasename
試しているトリミングは完全にサポートされています。
basename "$var" .ext
そうしないとzsh 拡張あなたがしようとしているものの全面的なサポート:
上記の name の代わりにタイプ ${...} のパラメーター式または $(...) タイプのコマンド置換を使用する場合は、最初に展開され、その結果が name の値であるかのように使用されます。したがって、入れ子になった操作を実行することが可能です。 ${${foo#head}%tail} は $foo 値を削除された 'head' と 'tail' に置き換えます。
だからzshで
echo ${${var##*/}%.*}
あなたが期待することを行います。
Bashで作業していて行を保存するには、sedを使用できます。
sed -e 's/\.[^.]*$//' <<<"${var##*/}"
.
これは、プレフィックスを失った後と同様に、最後の項目以降のすべての項目を正規表現に置き換えます。しかし、私はこれが2行のバージョンよりも特にメモリ効率であるとは思わず、おそらく理解するのは簡単ではありません。
全体的に同じ変数を使用できない理由はありません。
var2=${var##*/}
var2=${var2%.*}
割り当て前に拡張が行われるので安全です。非常に長いファイル名が2回保存されることが問題であれば、今はそのようなことは起こりませんが、現実的な問題ではないと思います。