Bash

使用預設值和 alt_value 進行參數擴展,丟棄參數值?

  • October 6, 2022

我僅限於 Bash。

我想回顯兩個字元串之一,具體取決於是否設置了參數。

比方說

if $ARG is notset|empty then print X
if $ARG is set&nonempty then print V

我對 $ARG 內容完全不感興趣。是否提供和填充。

我知道我可以通過 IF/CASE/etc 得到這個結果。但我會多次使用這個結構,我想保持簡潔。我知道我可以以任何方式做到這一點並將其包裝成一個函式,但我很好奇它是否可以以某種聰明的方式製作,即通過參數擴展?

我已經閱讀了https://tldp.org/LDP/abs/html/parameter-substitution.html和一些類似的頁面,我注意到有兩個類似的,看似互補的操作:

default value:      ${ARG:-X}
alternative value:  ${ARG:+V}

順便說一句,這就是問題標題的來源。:-為空時返回 X,非空時:+返回 V。

一個簡單的:

echo ${ARG:+V}${ARG:-X}

幾乎做我想要的。X$ARG為空或未設置時列印出來,但在任何其他情況下,比如 ARG=foo,它會列印出Vfoo. 那是因為:+並且:-並不是我想要的真正互補的方式;)要讓它與簡單的串聯一起工作,就像${}${}我需要一個“反向” :+,它在為空時輸出“預設”,或者什麼都不輸出(不是:測試的變數)。

似乎我需要一些類似的怪物複合命令${ARG:+V:-X}(它不起作用,因為它:+V:-Xalt_value 一起使用),它一次性完成,根據參數的狀態在兩個給定值之間進行選擇,並且不真正使用參數保存的實際文本。

我天真地嘗試嵌套

echo ${${ARG:+V}:-X}

這正是我需要的,它在 Bash 中不起作用,因為它是參數擴展,而內部${ARG:+V}不是參數,所以外部${}抱怨。(~命令替換可以嵌套在變數替換中嗎?

Vfoo我想我可以嘗試通過將其減少到第一個字元來修復${xxx:0:1},但是,這將需要再次嵌套${${ARG:+V}${ARG:-X}:0:1},所以不行。

或者一個輔助變數,在這種情況下它很好:

MINGW64 ~
$ f () { T=${1:+V}${1:-X} ; echo ${T:0:1} ; } ;

$ f "a"
V

$ f ""
X

$ f
X

這是我能得到的最接近的,甚至有我想要的行為。

感覺有點臟,因為它實際上構造任意長的字元串T只是為了得到它的第一個字元。純廢物。

此外,我仍然想將它壓縮成一個表達式,而不需要臨時變數T

我在 Bash 中錯過了什麼嗎?我可以通過參數擴展或任何其他內置技巧以更好的方式獲得這種“選擇”行為嗎?

您可以執行以下操作:

either=(
 'value for unset or empty'
 'value for set and non-empty'
)
printf '%s\n' "${either[!!${#VAR}]}"

set +o histexpand(如果從互動式 bash 呼叫中嘗試,則禁用歷史擴展 ( ))。

${#VAR}擴展為 的值中的字元數$VAR!!是雙重否定,!!${#VAR}因為如果變數為空或未設置,則算術表達式產生 0,否則產生 1。

使用zsh,您可以:

print -r -- ${${var:+value for set and non-empty}:-value for unset or empty}

引用自:https://unix.stackexchange.com/questions/719987