在 zsh 提示字元下重複 char n 次

在 zsh 提示字元下重複 char n 次

我正在處理自訂 ZSH 提示,我想n在字串中重複一個字元次(例如用於填充的空格)。該字串被列印print -rP(該-r標誌忽略回顯轉義約定,並且該-P標誌執行提示擴展)。

我有使用某種字串替換的工作代碼,但我不知道它是如何工作的。由於某種原因,我必須將要列印的字元數乘以二,這感覺就像駭客。

$ 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)為什麼乘以二會有效,

展開式"${(l:3::$c:)}"展開為c$cwhile"${(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(在有關參數擴展標誌的部分中):

pprint識別與此參數後面描述的任何標誌的內建字串參數   相同的轉義序列。

或者,使用此選項,字串參數可以採用以下形式,$var在這種情況下,將替換變數的值。請注意,此形式是嚴格的;字串參數不進行一般參數擴展。

答案2

使用你原來的符號,你可以實現你想要的,p使用開始參數標誌

 print "${(pl:$n::$c:)}"

有關更多資訊和其他一些有用的範例,請參閱 部分5.4.6:更多參數標誌第5章:替補zsh 指南。它提到了 uppercase 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) 標誌所解釋的那樣)始終成對出現在參數之前和之後,因此對於三個參數,中間的冒號會加倍。你可以錯過一部分:Y::X:一部分,看看會發生什麼。填充字串不需要是單一字元;如果它們在填充空間中不適合準確的次數,則最後一次重複將在距插入的參數參數最遠的一端被截斷。

兩個參數告訴 shell 您希望對參數替換的值執行一些特殊操作。 ( P) 標誌強制將該值視為參數名稱,以便獲得雙重替換的效果:

  % final=string
  % intermediate=final
  % print ${(P)intermediate}
  string

這有點像$intermediateksh 中所謂的 a nameref,一個被標記為對另一個參數的引用的參數。 Zsh 最終也可能擁有這些;在某些地方,它們比旗幟更方便(P)

更強大的標誌是 ( e),它強制重新掃描值以查找所有形式的單字替換。例如,

  % foo='$(print $ZSH_VERSION)'
  % print ${(e)foo}
  4.0.2

重新檢查的值$foo,此時找到並執行命令替換。

其餘標誌是一些簡單的特殊格式化技巧:使用 ( o) 按正常詞彙(字元)順序對數組元素進行排序,使用 ( ) 按相反順序排序,分別使用 ( ) 或 ( )O進行相同的大小寫無關,展開提示-用 ( ) 轉義(容易記住),像 print 用 p 那樣展開反斜杠轉義,用 ( ) 強制所有字符大寫或用 ( ) 小寫,用( ) 大寫字符串或每個數組元素的第一個字符,顯示特殊字符作為轉義序列,帶有 ( )。這應該足以繼續下去了。oiOi%%ULCV

相關內容