Zsh:変数値を代替パターンとして使用できますか?

Zsh:変数値を代替パターンとして使用できますか?

次のことは可能ですか?

g=$f:s/$in/$out/;

または

g=$g:s/$in[$i]/$out[$i]/;

${~in}私はandのようなランダムな文字の組み合わせを試しましたが、g=$g:ps/私はzshの専門家ではありません。推測は何らかの形で私には役に立ちません。 :-) マンページを読んでみました...

編集:独自のzmv型コマンドを作成しようとしています。

# in   a*b* -> a b NULL     rn a*b* *c*d   aXXbYY  -->  XXcYYd
# out  *c*d -> NULL c d     rn inv* mag*   inv.ext inv.spc -->  mag.ext mag.spc

alias rn='noglob frn'

function frn() {                                                                                                   
    local in out m n f g i
    setopt localoptions glob histsubstpattern

    in=("${(@s:*:)1}")                          # split $1 and $2 on '*'
    out=("${(@s:*:)2}")                         # keeping NULL fields

    m=${#in[@]}                                 # count n(array-elements)
    n=${#out[@]}

    if [[ $m = $n ]] {
        foreach f ($~1)                         # foreach file in globbed $1
            g=$f
            for (( i = 1; i < n; i += 1 )); do
                g=$g:s/$in[$i]/$out[$i]/        # subst corresponding fields
            done

            g=$g:s/%$in[$i]/$out[$i]/           # last subst has % anchor

            print '$f --> $g'
            mv $f $g
        end
    } else {
        print "n(*) must be same for both patterns"
    }
}

答え1

$out拡張とは異なり、$inこれはリテラル文字列として扱われるため、何も起こりません(リテラルがf含まれていない限り$in)。
左に展開するには、次のものが必要です。HIST_SUBST_PATTERN置く:

s/l/r[/]

r以下の説明に従って交換してくださいl
...
デフォルトでは、置換の左側はパターンではなく文字列です。 [...]
...このオプションが設定されている場合、
ファイル名生成フォームパターンに記載されているように通常どおりに処理されます。HIST_SUBST_PATTERNl

だから

setopt histsubstpattern

それではうまくいくでしょう...

答え2

試して再実装した方法はzmv -W非常に脆弱です。

rfn a*b*c b*c*d適用する前acrobaticにに変更する必要がありますbcrocatid

  • a -> b
  • b -> c
  • c-> d

継続的に、しかし、これは以下を生成します。

  • 曲芸 - >曲芸
  • 曲芸 - >曲芸
  • 曲芸 - >曲芸

zmv -W同じようにしてください

  1. 逆参照を有効にするa*b*cモードの変更(#b)a(*)b(*)c
  2. b*c*d交換を次のように変更します。b$match[1]c$match[2]d
  3. Kornスタイルまたはcsh-stypeを使用して${var/pattern/replacement}交換を実行するか、zsh 6.0+を使用して交換を実行します。$var:s/pattern/replacementhistsubstpattern:S修飾子モードの有無にかかわらず動作しますhistsubstpattern
function frn {
  emulate -L zsh
  set -o extendedglob
  local glob=$1 replacement=$2 n=0 file newfile

  pattern=${glob//'*'/'(*)'}
  replacement=${replacement//(#m)'*'/\$match[$((++n))]}

  for file ($~glob) {
    newfile=${file/#%(#b)$~pattern/${(Xe)replacement}}
    if [[ -n $newfile && $file != $newfile ]] {
      print -ru2 -- "${(q+)file} -> ${(q+)newfile}"
      # mv -- $file $newfile
    }
  }
}
alias frn='noglob frn'

それから:

$ frn a*b*c b*c*d
acrobatic -> bcrocatid

それは次のとおりです。

$ alias zmvw='noglob zmv -W'
$ zmvw -n a*b*c b*c*d
mv -- acrobatic bcrocatid

zmvより多くのワイルドカードを処理できるだけでなく、*より多くの健全性チェックとエラー処理も実行できます。

関連情報