Shell – What does “${line#*’Caused By’}” != “$line” mean in a shell script

shellshell-script

Can someone explain what this means in a shell script?

while read -r line
do 
  if [ "${line#*'Caused By'}" != "$line" ]; then
    echo "Yes"
  fi
done       

Best Answer

${line#*'Caused By'} is a specific instance of the variable substitution ${parameter#word} (as it's written in the bash manual, and also in the POSIX standard for the sh shell).

In ${parameter#word}, the pattern word will be removed from the beginning of the value of $parameter. It's called "Remove Smallest Prefix Pattern" because it will remove the shortest matching prefix string that matches the pattern in word (with ## in place of # it removes the longest matching prefix string).

It this specific example, the string Caused by (and anything before it, thanks to the *) is, if it exists, removed from the value of $line. The single quotes around the string are redundant.

By comparing the result of the substitution with the value of the variable itself, the test determines whether the value of $line contains the text Caused by, and prints Yes if it does.

This has the same effect as

if [[ "$line" == *'Caused by'* ]]; then
    echo 'Yes'
fi

in bash, ksh93 or zsh, or

case "$line" in
    *'Caused by'*) echo 'Yes'
esac

in any sh shell.


The loop in the question reads "lines" from standard input. See the question "Understanding "IFS= read -r line" " for a discussion about this.

Related Question