次のファイルを含むディレクトリがあるとします。
touch doc-mike.txt doc-jane.txt doc-susan.txt
次の構造を使用して、スクリプト内のこれらのファイルに対して特定のタスクを実行できます。
for fname in doc-*.txt; do
echo input: ${fname}
done
ただし、ワイルドカードに一致するファイル名の部分文字列を取得するには、いくつかの難しいプロセスが必要です。
for fname in doc-*.txt; do
wildcard=${fname#doc-}
wildcard=${wildcard%.txt}
echo input: ${fname} output: output-${wildcard}.results
done
これは働きます:
input: doc-jane.txt output: output-jane.results
input: doc-mike.txt output: output-mike.results
input: doc-susan.txt output: output-susan.results
"*"
しかし、globワイルドカードと一致する部分文字列を取得するためのより良い/簡単な方法が必要だと思います。
答え1
私が考えることができる最も近いのは、BASH_REMATCH
bashが正規表現リテラルの結果をその変数に格納するためです。
$ for fname in doc-*.txt; do
[[ $fname =~ doc-(.*).txt ]];
echo "input: ${fname} output: output-${BASH_REMATCH[1]}.results";
done
input: doc-jane.txt output: output-jane.results
input: doc-mike.txt output: output-mike.results
input: doc-susan.txt output: output-susan.results
(.*)
正規表現の最初のグループと同様にBASH_REMATCH[1]
。
答え2
zsh
混ぜることができます。glob修飾子、履歴拡張修飾子、globbingフラグ行ってください。
以下で、拡張ワイルドカードと記録パターンの交換モードを有効にしたとします。
setopt extendedglob
setopt histsubstpattern
だからあなたは実行することができます
print doc-*.txt(#q:s/(#b)doc-(*).txt/'${match[1]}'/)
これは出力されます
jane mike susan
通常どおり、これを通常のファイルのみを選択したり、単語の先頭/末尾に式を固定するなど、他の修飾子/修飾子/フラグと組み合わせることができます。
ただし、各ファイル名を繰り返す場合は、zsh
パラメータ拡張をネストしてコードを次のように単純化できます。
for fname in doc-*.txt; do
print input: ${fname} output: output-${${fname#doc-}%.txt}.results
done
上記(返信:あなたのコメント)は単一の式を使用し、中間変数は必要ありません。
答え3
また試すことができます
for fname in doc-*.txt; do
echo "input: ${fname} output: output-${fname:4:$((${#fname}-8))}.results"
done