2013-01-24 151 views
49
for i in $(ls);do 
    if [ $i = '*.java' ];then 
     echo "I do something with the file $i" 
    fi 
done 

我想遍历当前文件夹中的每个文件并检查它是否与特定扩展名匹配。上面的代码不起作用,你知道为什么吗?循环遍历所有具有特定扩展名的文件

+2

什么'因为我在$(LS *。JAVA);做回声“用文件$ i做些什么”; done'? – speakr

+0

为什么不使用find? – Kent

+0

有没有办法解决,如果陈述? – AR89

回答

99

没有华丽的技巧需要:

for i in *.java; do 
    [ -f "$i" ] || break 
    ... 
done 

防护确保,如果没有匹配的文件,循环将退出而不试图处理一个不存在的文件名*.java。在bash(或支持类似的外壳)中,可以使用nullglob选项 来简单地忽略失败的匹配并且不输入循环的主体。

shopt -s nullglob 
for i in *.java; do 
    ... 
done 
+0

如何更改此设置以遍历所有* .java和* .cpp文件? – Temak

+4

最简单的方法是添加另一个模式:'为我in * .java * .cpp; do'。如果你在'bash'中使用'shopt -s extglob'启用了扩展模式,你可以写'for i in *。@(java | cpp); do'。 – chepner

+7

它会如果它实际上匹配任何文件。你需要使用'shopt -s nullglob',这样一个不匹配的模式扩展到空序列而不是被直接处理。 – chepner

3

正如@chepner在他的评论中说的,你将$ i与固定字符串进行比较。

扩大和纠正你应该使用[[]]用正则表达式运算符的情况=〜

如:

for i in $(ls);do 
    if [[ $i =~ .*\.java$ ]];then 
     echo "I want to do something with the file $i" 
    fi 
done 

的正则表达式的=〜抵抗值测试的权(引用不会错误,但会与固定字符串进行比较,因此很可能会失败“

但是,使用glob的@chepner的回答是更有效的机制。

+0

如何用变量'ext'代替'.java'? – AR89

+1

ack,不需要正则表达式:'if [[$ i == * .java]]'或'if [[$ i == *。$ ext]]''。但[不要分析ls](http://mywiki.wooledge.org/ParsingLs) –

+1

Downvote:http://mywiki.wooledge.org/ParsingLs – tripleee

9

正确的答案是@ chepner的

EXT=java 
for i in *.${EXT}; do 
    ... 
done 

但是,这里有一个小窍门,以检查文件名是否有一个给定的扩展:

EXT=java 
for i in *; do 
    if [ "${i}" != "${i%.${EXT}}" ];then 
     echo "I do something with the file $i" 
    fi 
done 
+0

它将如何与变量'ext'而不是''。 java'? – AR89

+0

我更新了示例以使用EXT –

1

我同意枝条关于正确的方式向其他答案循环遍历文件。然而OP问:

上面的代码不起作用,你知道为什么吗?

是的!

的优秀文章 What is the difference between test, [ and [[ ?]的细节,还有其他一些区别,你不能在test命令中使用expression matchingpattern matching(这是简写[)解释

 

Feature   new test [[ old test [   Example 

Pattern matching = (or ==) (not available) [[ $name = a* ]] || echo "name does not start with an 'a': $name" 

Regular Expression  =~  (not available) [[ $(date) =~ ^Fri\ ...\ 13 ]] && echo "It's Friday the 13th!" 
matching 

这是你的脚本失败的原因。如果OP对[[语法的回答感兴趣(其缺点是在[命令的平台上不受支持),我很乐意编辑我的答案以包含它。

编辑:如何格式化答案中的数据作为表的任何protip将有所帮助!

4

递归添加子文件夹,

for i in `find . -name "*.java" -type f`; do 
    echo $i 
done 
+0

而不是'find。 -name“* .java”-type f -exec echo \ {\} \;'以避免错误地分析'find'的输出 –

+1

如果你不这样做,至少应该在里面引用''$ i“'循环。 – tripleee

相关问题