如何在shellscript中匹配特定的文件扩展名

时间:2019-01-19 21:39:49

标签: bash shell

我看了一些其他帖子,并学会了按以下方式匹配文件扩展名,但是为什么我的代码不起作用?谢谢。

  1 #!/bin/sh
  2 
  3 for i in `ls`
  4 do
  5     if [[ "$i" == *.txt ]]
  6     then
  7         echo "$i is .txt file"
  8     else
  9         echo "$i is NOT .txt file"
 10     fi
 11 done

eidt: 我意识到#!/bin/sh#!/bin/bash是不同的,如果您稍后再看这篇文章,请记住检查使用的是哪一个。

3 个答案:

答案 0 :(得分:2)

[[ ]]表达式仅在某些shell中可用,例如bash和zsh。一些更基本的shell(例如破折号)不支持它。我猜您正在Ubuntu或Debian的最新版本上运行此程序,其中/ bin / sh实际上是破折号,因此无法识别[[。实际上,无论如何,您都不应将[[ ]]#!/bin/sh一起使用,因为依靠shebang不需要的功能是不安全的。

那么,该怎么办?您将获得[ ]类型的测试表达式,但它不会进行模式匹配(例如*.txt)。有很多其他方法可以做到这一点:

  • The case statement 甚至在基本shell中都可用,并且具有与[[ = ]]相同的模式匹配功能。这是执行此类操作的最常见方法,尤其是当您有一系列要检查的不同模式时。

  • 更间接地说,您可以使用${var%pattern}尝试从值末尾删除.txt(请参阅“删除最小后缀模式” here),然后然后检查是否更改了该值:

    if [ "$i" != "${i%.txt}" ]
    

    更多说明:假设$i是“ file.txt”;然后它扩展为[ "file.txt" != "file" ],因此它们不相等,并且测试(对于!=)成功。另一方面,如果$i是“ file.pdf”,则它将扩展为[ "file.pdf" != "file.pdf" ],由于字符串相同,该操作将失败。

    其他说明:使用[ ]时,请使用单个等号进行字符串比较,并确保正确地对所有变量引用加双引号以避免混淆。另外,如果您使用对外壳具有特殊含义的任何内容(例如<>),则需要引用或转义它们。

  • 您可以使用expr命令的:运算符进行正则表达式匹配。 (正则表达式是与基本通配符或“ glob”表达式不同的模式类型。)您可以这样做,但是不能。

答案 1 :(得分:0)

#!/bin/sh

for i in `ls`
do
   if [[ "$i" = *".txt" ]] ; then
       echo "$i is .txt file"
   else
       echo "$i is NOT .txt file"
   fi
done

答案 2 :(得分:0)

您不必循环进入ls输出,并且的实现可能因操作系统发行版而异。

考虑:

#! /bin/sh

for i in *

do

  if [[ "$i" == *.txt ]]

  then

    echo "$i is txt file"

  else

    echo "$i is NOT txt file"

  fi

done