zsh配列のすべての要素に部分文字列拡張を適用できますか?

zsh配列のすべての要素に部分文字列拡張を適用できますか?

配列のすべての要素から最初の2文字と最後の3文字を削除したいとしましょう。

results=( QK9H9UtADCgnG AlaLkCADjQ krsxseW8H1VrU 6nBG94ZbCWQ )

終わりたい

results=( 9H9UtADC aLkCA sxseW8H1 BG94Zb )

要素を繰り返し、部分文字列拡張が配列の代わりに各要素に影響を与えるために使用することに加えて、同様の${element:2:-3}操作を実行できるフラグまたはいくつかの組み合わせがありますか?${(⭕)results:2:-3}


重要な場合、私の特別なケースでは配列が機能します。いいえ空の要素があります。要素は次のとおりです。いいえあらゆる種類の空白文字を含み、抽出規則は常に左>P+Sそれはエルすべての要素の長さは、常に要素の総長より長くなります。Sサフィックスの合計削除したい内容を編集してください。
私は文字列を修正し、テキスト処理ツールを使用することに興味がありません。上記のように、現在ループスルー機能を使用しているので、入力を減らすことは問題ではなく、マニュアルを見てみましたが、できないのでこれが可能かどうか疑問に思います。これを行う方法を見つけます。

ベストアンサー1

ksh93から来るのは${string:offset:length}zshにはデフォルトではなく、ksh93 / bashとの互換性のために最近追加されました。

zshではこれを行うことをお勧めします$string[first,last](ksh93より前)。

しかし、とにかくzshでも$var[first,last]ksh93-style${var:offset:length}でも、これらは文字列と配列に適用できる演算子です(bash / kshとは異なり、zshでは配列とスカラーは2つの別々の変数型なので、演算子を異なる方法で適用できます)。 )、最初のケースでは部分文字列を提供し、2番目のケースでは要素のサブセットを提供します。

私が知っている限り、これは配列全体ではなく各文字列要素に適用されることをzshに伝えることはできません。

${results[1][3,-4]}(または${results[1]:2:-3})は機能しますが、文字列ではなく配列を生成しないため、${results[1,2][3,-4]}配列として適用されます。${results[1,2]}[3,-4]

しかし、ここでは他のアプローチをとることができます。

たとえば、各要素に${string#pattern}ksh スタイル演算子を適用できます。${string%pattern}

results=( ${${results#??}%???} )

または、先行および末尾の文字を必要なだけ削除します。

set -o extendedglob
results=( ${${results#?(#c5)}%?(#c8)} )

ksh93スタイルを使用して各要素を任意に変更することもできます${array/pattern/replacement}。たとえば、次のようになります。

set -o extendedglob
results=( ${results/(#m)*/$MATCH[3,-4]} )

また、見ることができます

results=( ${results/(#b)??(*)???/$match[1]} )

これにより、5文字以上の要素のみが変更されます(results=( "${results[@]/??@(*)???/\1}" )ksh93と同じ)。

別の複雑なアプローチ:

() { results=( ${(e)argv} ); } '${results['{1..$#results}'][3,-4]}'

${results[1][3,-4]} ${results[2][3,-4]}私たちはフラグを使用してeそれを評価し、配列に再割り当てする匿名関数にetcを渡します。

[@](これらすべての中で、剪定後に空の要素を含む空の要素を保持するには、withと引用符を使用してください。)

おすすめ記事