Bash:通过分组命令和布尔运算符实现不带 IF 的条件语句

Rog*_*ger 0 bash conditional-formatting conditional-statements

我正在尝试从 Bash 脚本中消除“if”语法:

N=
MD='title|1.md' 
Run Code Online (Sandbox Code Playgroud)

这按预期工作(打印“1”和“title_1”):

if [ $(echo "$MD" | grep '|') ]; then N="${MD#*|}"; ID=${MD%|*}'_'$N; fi
echo "$N" ; echo "$ID" 
Run Code Online (Sandbox Code Playgroud)

这不会(打印空):

[[ $(echo $MD | grep '|') ]] && $(N="${MD#*|}" ; ID=${MD%|*}'_'$N)
echo "$N" ; echo "$ID" 
Run Code Online (Sandbox Code Playgroud)

使用它运行脚本bash +x会返回:

+ N=
++ echo 'title|1'
++ grep '|'
+ [[ -n title|1 ]]
++ N=1
++ ID=title_1
+ echo ''

+ echo ''

+ exit
Run Code Online (Sandbox Code Playgroud)

有谁能告诉我我做错了什么?谢谢。

che*_*ner 5

命令替换启动一个子 shell(在这种情况下,如果有任何输出,捕获的输出将作为命令运行)。你想要一个指挥组。

# Skip grep as well
[[ $MD = *\|* ]] && { N=${MD#*|}; ID=${MD%|*}_$N; }
Run Code Online (Sandbox Code Playgroud)

正则表达式可以为您捕获 的每一面|,从而消除后面的操作的需要MD

[[ $MD =~ (.*)\|(.*) ]] && { N=${BASH_REMATCH[2]}; ID=${BASH_REMATCH[1]}_$N; }
Run Code Online (Sandbox Code Playgroud)

如果您担心可读性,请不要尝试将所有内容都放在一行中。

if [[ $MD =~ (.*)\|(.*) ]]; then
  N=${BASH_REMATCH[2]}
  ID=${BASH_REMATCH[1]}_$N
fi
Run Code Online (Sandbox Code Playgroud)