我看了一些其他帖子,并学会了按以下方式匹配文件扩展名,但是为什么我的代码不起作用?谢谢。
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
是不同的,如果您稍后再看这篇文章,请记住检查使用的是哪一个。
答案 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
输出,并且sh的实现可能因操作系统发行版而异。
考虑:
#! /bin/sh
for i in *
do
if [[ "$i" == *.txt ]]
then
echo "$i is txt file"
else
echo "$i is NOT txt file"
fi
done