bash 循环遍历所有具有特定扩展名的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14505047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:15:42  来源:igfitidea点击:

Loop through all the files with a specific extension

bashfileglob

提问by AR89

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

I want to loop through each file in the current folder and check if it matches a specific extension. The code above doesn't work, do you know why?

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

回答by chepner

No fancy tricks needed:

不需要花哨的技巧:

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

The guard ensures that if there are no matching files, the loop will exit without trying to process a non-existent file name *.java. In bash(or shells supporting something similar), you can use the nullgloboption to simply ignore a failed match and not enter the body of the loop.

守卫确保如果没有匹配的文件,循环将退出而不尝试处理不存在的文件名*.java。在bash(或支持类似内容的 shell)中,您可以使用该nullglob选项来简单地忽略失败的匹配而不进入循环体。

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

回答by uml?ute

the correct answer is @chepner's

正确答案是@chepner

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

however, here's a small trick to check whether a filename has a given extensions:

但是,这里有一个小技巧来检查文件名是否具有给定的扩展名:

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

回答by luismartingil

Recursively add subfolders,

递归添加子文件夹,

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

回答by Benny

Loop through all files ending with: .img, .bin, .txtsuffix, and print the file name:

遍历所有以: .img, .bin,.txt后缀结尾的文件,并打印文件名:

for i in *.img *.bin *.txt;
do
  echo "$i"
done

Or in a recursive manner (find also in all subdirectories):

或者以递归方式(也在所有子目录中找到):

for i in `find . -type f -name "*.img" -o -name "*.bin" -o -name "*.txt"`;
do
  echo "$i"
done

回答by user000001

I agree withe the other answers regarding the correct way to loop through the files. However the OP asked:

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

The code above doesn't work, do you know why?

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

Yes!

是的!

An excellent article What is the difference between test, [ and [[ ?] explains in detail that among other differences, you cannot use expression matchingor pattern matchingwithin the testcommand (which is shorthand for [)

一篇很棒的文章test, [ 和 [[ ?] 之间有什么区别,详细解释了在其他区别中,您不能在命令中使用expression matching或(这是 的简写)pattern matchingtest[

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

So this is the reason your script fails. If the OP is interested in an answer with the [[syntax (which has the disadvantage of not being supported on as many platforms as the [command), I would be happy to edit my answer to include it.

所以这就是你的脚本失败的原因。如果 OP 对使用[[语法的答案感兴趣(它的缺点是不受与[命令一样多的平台支持),我很乐意编辑我的答案以包含它。

EDIT: Any protips for how to format the data in the answer as a table would be helpful!

编辑:有关如何将答案中的数据格式化为表格的任何提示都会有所帮助!

回答by peteches

as @chepner says in his comment you are comparing $i to a fixed string.

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

To expand and rectify the situation you should use [[ ]] with the regex operator =~

要扩展和纠正这种情况,您应该使用 [[ ]] 和正则表达式运算符 =~

eg:

例如:

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

the regex to the right of =~ is tested against the value of the left hand operator and should not be quoted, ( quoted will not error but will compare against a fixed string and so will most likely fail"

=~ 右侧的正则表达式针对左侧运算符的值进行测试,不应引用,(引用不会出错,但会与固定字符串进行比较,因此很可能会失败”

but @chepner 's answer above using glob is a much more efficient mechanism.

但是@chepner 上面使用 glob 的回答是一种更有效的机制。

回答by f0nzie

I found this solution to be quite handy. It uses the -oroption in find:

我发现这个解决方案非常方便。它使用以下-or选项find

find . -name \*.tex -or -name "*.png" -or -name "*.pdf"

find . -name \*.tex -or -name "*.png" -or -name "*.pdf"

It will find the files with extension tex, png, and pdf.

它会找到的文件扩展名为texpngpdf