Dave
Dave

Reputation: 421

How do we match a suffix in a string in bash?

I want to check if an input parameter ends with ".c"? How do I check that? Here is what I got so far (Thanks for your help):

#!/bin/bash

for i in $@
do
    if [$i ends with ".c"]
    then
            echo "YES"
        fi
done

Upvotes: 25

Views: 20384

Answers (3)

tripleee
tripleee

Reputation: 189317

A classical case for case!

case $i in *.c) echo Yes;; esac

Yes, the syntax is arcane, but you get used to it quickly. Unlike various Bash and POSIX extensions, this is portable all the way back to the original Bourne shell.

Tangentially, you need double quotes around "$@" in order for it to correctly handle quoted arguments.

Upvotes: 30

Alexey Kondakov
Alexey Kondakov

Reputation: 210

for i in "$@"; do
    if [ -z ${i##*.c} ]; then
        echo "YES: $i"
    fi
done


$ ./test.sh .c .c-and-more before.c-and-after foo.h foo.c barc foo.C
YES: .c
YES: foo.c
$

Explanation (thanks to jpaugh):

  1. Iterate over command line arguments: for i in $@; do
  2. Main trick is here: if [ -z ${i##*.c} ]; then. Here we check if length of string ${i##*.c} is zero. ${i##*.c} means: take $i value and remove substring by template "*.c". If result is empty string, then we have ".c" suffix.

Here if some additional info from man bash, section Parameter Expasion

${parameter#word}
${parameter##word}
    Remove matching prefix pattern.  The word is expanded to produce a pat‐
    tern just as in pathname expansion.  If the pattern matches the  begin‐
    ning of the value of parameter, then the result of the expansion is the
    expanded value of parameter with the  shortest  matching  pattern  (the
    ``#''  case) or the longest matching pattern (the ``##'' case) deleted.
    If parameter is @ or *, the pattern removal  operation  is  applied  to
    each  positional  parameter in turn, and the expansion is the resultant
    list.  If parameter is an array variable subscripted with @ or  *,  the
    pattern  removal  operation  is  applied to each member of the array in
    turn, and the expansion is the resultant list.

Upvotes: 13

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798526

$ [[ foo.c = *.c ]] ; echo $?
0
$ [[ foo.h = *.c ]] ; echo $?
1

Upvotes: 19

Related Questions