bash 中的参数扩展如何评估匹配?

bash 中的参数扩展如何评估匹配?

我读《Linux圣经第10版》,第 7 章:编写简单的 Shell 脚本,第 149 页, “bash 中的参数扩展”段落。

  • ${var:-value}— 如果变量未设置或为空,则将其扩展为值。
  • ${var#pattern}— 从 var 值的前面截取最短的模式匹配。
  • ${var##pattern}- 从 var 值的前面截取最长的模式匹配。
  • ${var%pattern}— 从 var 值的末尾截取最短的模式匹配。
  • ${var%%pattern}- 从 var 值的末尾截取最长的模式匹配。

请向我解释一下,如何最长/最短匹配是计算出来的?从右到左还是相反?

另外,请解释一下下面的代码是如何工作的以及如何计算输出

MYFILENAME=”/home/digby/myfile.txt”—Sets the value of MYFILENAME 
FILE=${MYFILENAME##*/}—FILE becomes "myfile.txt" 
DIR=${MYFILENAME%/*}—DIR becomes "/home/digby" 
NAME=${FILE%.*}—NAME becomes "myfile" 
EXTENSION=${FILE##*.}—EXTENSION becomes "txt"

谢谢。

答案1

让我们从从前面切开的“#”案例开始。考虑一个字符串,例如myfile.tar.gz.如果将其与字符串*.(这意味着“零个或多个字符”后跟句号)进行匹配,则有两种可能的匹配:myfile.myfile.tar.。这最短匹配是:

${MYFILENAME#*.} # ie myfile.

所以结果就是剩下的:tar.gz。这最长匹配是:

${MYFILENAME##*.} # ie myfile.tar.

所以结果就是剩下的:gz

现在考虑“%”的情况。这里匹配位于字符串的右侧。这次与.*.我们正在寻找一个点后带有一些(或没有)字符的点。最短的匹配是.gz最长的,.tar.gz所以我们得到:

${MYFILENAME%.*}  # => myfile.tar
${MYFILENAME%%.*} # => myfile

您的其他示例是主题的变体来说明这一点:

MYFILENAME=”/home/digby/myfile.txt”—Sets the value of MYFILENAME 
FILE=${MYFILENAME##*/}—FILE becomes "myfile.txt" 
DIR=${MYFILENAME%/*}—DIR becomes "/home/digby" 
NAME=${FILE%.*}—NAME becomes "myfile" 
EXTENSION=${FILE##*.}—EXTENSION becomes "txt"

解释:

  1. */从前面开始匹配的最长字符串是/home/digby/
  2. /*末尾匹配的最短字符串是/myfile.txt
  3. 末尾匹配 .* 的最短字符串是.txt
  4. at the front is匹配“* .myfile.`的最长字符串

相关内容