
n
私はカスタムZSHプロンプトで作業しており、文字列(パディングのためのスペースなど)で文字を何度も繰り返したいと思います。文字列が印刷されますprint -rP
(この-r
フラグはエコーエスケープルールを無視し、この-P
フラグはプロンプト拡張を実行します)。
ある種の文字列置換を使用する作業コードがありますが、どのように機能するのかわかりません。何らかの理由で印刷する文字数に2を掛ける必要があります。これはハッキングのように感じます。
$ n=3
$ c='a'
$ print -rP "${(l:$n::$c:)}" # why doesn't this work?
ca
$ print -rP "${(l:(( $n * 2 ))::$c:)}" # but this does?
aaa
それでは、1)2を掛けることが機能する理由と2)文字列で文字を繰り返す正しい構文は何ですか?
答え1
1)2を掛けることが機能するのはなぜですか?
拡張はに展開され、"${(l:3::$c:)}"
拡張c$c
されます。このオプションが設定され、文字列がプロンプト文字列の一部として使用される場合、引数拡張、コマンド置換、および算術拡張について評価されます。したがって、もし、thenになります。"${(l:3*2::$c:)}"
$c$c$c
PROMPT_SUBST
c=a
c$c
ca
$c$c$c
aaa
コレクションでテストしてくださいXTRACE
。
$ n=3 c=a zsh -o PROMPT_SUBST -xc 'print -rP -- "${(l:n::$c:)}"'
+zsh:1> print -rP -- 'c$c'
ca
$ n=3 c=a zsh -o PROMPT_SUBST -xc 'print -rP -- "${(l:n*2::$c:)}"'
+zsh:1> print -rP -- '$c$c$c'
aaa
2)文字列で文字を繰り返す正しい構文は何ですか?
すでに使用しているのと同じ方法でパラメータ拡張フラグをl
使用してください。しかし、このフラグは、文字列引数がp
埋められる前に$c
変数の値として扱われるようにする必要がありますc
(これを指摘した@StéphaneChazelasに感謝します)。
$ n=3 c=a zsh -xc 'print -r -- "${(pl:n::$c:)}"'
+zsh:1> print -r -- aaa
aaa
man zshexpn
(パラメータ拡張フラグセクションにあります)によると、これはこの設定で許可される唯一のパラメータ拡張形式です。
p
または、このオプションを使用すると、文字列引数は次の形式を取ることができます。
$var
この場合、変数の値が置き換えられます。この形式は厳密です。文字列パラメータは一般的なパラメータ拡張を受けません。
答え2
p
元の表記法を使用すると、必要なものを得ることができます。スタートパラメータフラグ
print "${(pl:$n::$c:)}"
詳細やその他の有用な例については、セクションを参照してください。5.4.6:追加パラメータフラグ存在する第5章:代替zshガイド。大文字は言及されていますが、以下は言及されてP
いませんp
。
これにはいくつかの異なるパラメータフラグがあります。そのうちのいくつかを繰り返します。非常に便利な方法は、t
パラメータの種類を知らせることです。これは3章にも出てきます。最も一般的な用途は、パラメータを使用する前にパラメータの基本タイプをテストすることです。
if [[ ${(t)myparam} != *assoc* ]]; then
# $myparam is not an associative array. Do something about it.
fi
別の非常に便利なタイプは、文字列を指定された長さで左右に埋めることです。オプションで、空白の代わりに指定されたパディング文字列を使用すると、関連する文字列のすぐ隣に使い捨て文字列を指定することもできます。
foo='abcdefghij'
for (( i = 1; i <= 10; i++ )); do
goo=${foo[1,$i]}
print ${(l:10::X::Y:)goo} ${(r:10::X::Y:)goo}
done
かなり素敵に印刷されます。
XXXXXXXXYa aYXXXXXXXX
XXXXXXXYab abYXXXXXXX
XXXXXXYabc abcYXXXXXX
XXXXXYabcd abcdYXXXXX
XXXXYabcde abcdeYXXXX
XXXYabcdef abcdefYXXX
XXYabcdefg abcdefgYXX
XYabcdefgh abcdefghYX
Yabcdefghi abcdefghiY
abcdefghij abcdefghij
s
これらのコロン(()および()フラグについてj
説明したように、他の文字にすることができます)は常にパラメータの前後にペアで表示されるため、3つのパラメータの場合は中間コロンが2倍になります。部分を:Y:
1つずつ見逃して、何が起こるのかを見ることができます:X:
。パディング文字列は単一文字である必要はありません。パディングスペースに正確な回数が合わない場合、最後の反復は挿入された引数引数から最も遠い端で切り捨てられます。
両方のパラメータは、パラメータで置き換えられた値に対して特別なアクションを実行したいシェルを示します。 (P
)フラグは、値がパラメータ名として扱われるように強制し、二重置換効果を取得します。
% final=string
% intermediate=final
% print ${(P)intermediate}
string
これは、他のパラメータへの参照として表示されるパラメータ$intermediate
kshから呼び出されるものと少し似ています。nameref
Zshは最終的にこれらの機能を持つことができ、いくつかの場所ではフラグよりも便利です(P)
。
より強力なフラグは(e
)で、すべての形式の単一単語置換に対して値を再取得します。例えば、
% foo='$(print $ZSH_VERSION)'
% print ${(e)foo}
4.0.2
値を再確認し、$foo
コマンド置換を見つけて実行します。
残りのフラグは、いくつかの単純な特殊書式設定トリックです。o
配列要素を通常の語彙(文字)順にソートするには()を使用し、逆順にソートするには()を使用し、大文字と小文字を区別せずに同じ操作を実行するにはそれぞれ()または()を使用しO
、拡張します。ヒント - ()でエスケープする(覚えやすい)、printのようにバックスラッシュエスケープをpに展開し、すべての文字を()で大文字または()で小文字に、大文字の文字列または()で各配列要素を表示する最初番目の文字エスケープシーケンスである特殊文字の前には()が付きます。続行するにはこれで十分です。oi
Oi
%
%
U
L
C
V