"${line#*'Caused By'}" != "$line" 在 shell 脚本中是什么意思?

sri*_*tal 7 shell shell-script

有人可以在shell脚本中解释这意味着什么吗?

while read -r line
do 
  if [ "${line#*'Caused By'}" != "$line" ]; then
    echo "Yes"
  fi
done       
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 12

${line#*'Caused By'}是变量替代的特定实例${parameter#word}(因为它是写中bash手册,并且还在POSIX标准sh壳)。

在 中${parameter#word},模式word将从 的值的开头移除$parameter。之所以称为“删除最小前缀模式”,是因为它将删除与其中的模式匹配的最短匹配前缀字符串word##代替#它删除最长的匹配前缀字符串)。

在这个特定示例中,字符串Caused by(以及它之前的任何内容,感谢*),如果存在,将从 的值中删除$line。字符串周围的单引号是多余的。

通过将替换结果与变量本身的值进行比较,测试确定 的值是否$line包含 text Caused byYes如果包含则打印。

这与效果相同

if [[ "$line" == *'Caused by'* ]]; then
    echo 'Yes'
fi
Run Code Online (Sandbox Code Playgroud)

bash,ksh93zsh, 或

case "$line" in
    *'Caused by'*) echo 'Yes'
esac
Run Code Online (Sandbox Code Playgroud)

在任何sh外壳中。


问题中的循环从标准输入中读取“行”。有关此问题 的讨论,请参阅问题“理解“IFS= read -r line” ”。


Ste*_*n M 6

if 条件的左侧使用bash的模式匹配功能。如果匹配的字符串包含“Caused By”,则将删除匹配的字符串。该行将不再与之前相同,因此不会触发 if 子句。

下面是一个可以在 shell 上运行的示例:

echo -e "Number 1 Caused by me.\nNumber 2 is normal.\n" |
  while read line; do
    echo "${line#*'Caused by'}"
  done
Run Code Online (Sandbox Code Playgroud)

结果:

 me.
Number 2 is normal.
Run Code Online (Sandbox Code Playgroud)