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

发布于 2024-12-10 08:44:52 字数 183 浏览 0 评论 0原文

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

#!/bin/bash

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

错々过的事 2024-12-17 08:44:52

case 的经典案例!

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

是的,语法很晦涩,但你很快就会习惯它。与各种 Bash 和 POSIX 扩展不同,它可以一直移植到原始的 Bourne shell。

切线而言,您需要在 "$@" 周围加上双引号,以便它正确处理带引号的参数。

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.

肩上的翅膀 2024-12-17 08:44:52
$ [[ foo.c = *.c ]] ; echo $?
0
$ [[ foo.h = *.c ]] ; echo $?
1
$ [[ foo.c = *.c ]] ; echo $?
0
$ [[ foo.h = *.c ]] ; echo $?
1
堇年纸鸢 2024-12-17 08:44:52
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} ];然后。这里我们检查字符串 ${i##*.c} 的长度是否为零。 ${i##*.c} 意思是:取$i值并通过模板“*.c”删除子字符串。如果结果是空字符串,则我们有“.c”后缀。

这里是来自 man bash 的一些附加信息,参数扩展部分

${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.
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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文