我们如何在bash中匹配字符串中的后缀?

时间:2011-10-18 05:25:13

标签: bash pattern-matching

我想检查输入参数是否以“.c”结尾?我该如何检查?这是我到目前为止所得到的(感谢您的帮助):

#!/bin/bash

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

3 个答案:

答案 0 :(得分:13)

case的经典案例!

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

是的,语法是神秘的,但你很快就习惯了。与各种Bash和POSIX扩展不同,它可以移植到最初的Bourne shell。

答案 1 :(得分:8)

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

答案 2 :(得分:1)

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
$

解释(感谢jpaugh):

  1. 迭代命令行参数:for i in $@; do
  2. 主要技巧在这里:if [ -z ${i##*.c} ]; then。在这里,我们检查字符串${i##*.c}的长度是否为零。 ${i##*.c}表示:获取$ i值并按模板“* .c”删除子字符串。如果结果是空字符串,那么我们有“.c”后缀。
  3. 这里有一些来自man bash的附加信息,参数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.