递归查找具有特定扩展名的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5927369/
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-08-04 00:51:09  来源:igfitidea点击:

Recursively look for files with a specific extension

linuxbashrecursion

提问by flip

I'm trying to find all files with a specific extension in a directory and its subdirectories with my bash (Latest Ubuntu LTS Release).

我正在尝试使用我的 bash(最新的 Ubuntu LTS 版本)在目录及其子目录中查找具有特定扩展名的所有文件。

This is what's written in a script file:

这是写在脚本文件中的内容:

#!/bin/bash

directory="/home/flip/Desktop"
suffix="in"

browsefolders ()
  for i in ""/*; 
  do
    echo "dir :$directory"
    echo "filename: $i"
    #   echo ${i#*.}
    extension=`echo "$i" | cut -d'.' -f2`
    echo "Erweiterung $extension"
    if     [ -f "$i" ]; then        

        if [ $extension == $suffix ]; then
            echo "$i ends with $in"

        else
            echo "$i does NOT end with $in"
        fi
    elif [ -d "$i" ]; then  
    browsefolders "$i"
    fi
  done
}
browsefolders  "$directory"

Unfortunately, when I start this script in terminal, it says:

不幸的是,当我在终端中启动这个脚本时,它说:

[: 29: in: unexpected operator

(with $extensioninstead of 'in')

(用$extension代替'in'

What's going on here, where's the error? But this curly brace

这是怎么回事,错误在哪里?但是这个花括号

回答by Mat

find $directory -type f -name "*.in"

is a bit shorter than that whole thing (and safer - deals with whitespace in filenames and directory names).

比整个事情短一点(并且更安全 - 处理文件名和目录名中的空格)。

Your script is probably failing for entries that don't have a .in their name, making $extensionempty.

对于.名称中没有 a 的条目,您的脚本可能会失败,从而为$extension空。

回答by Jens

  1. There's a {missing after browsefolders ()
  2. All $inshould be $suffix
  3. The line with cutgets you only the middle part of front.middle.extension. You should read up your shell manual on ${varname%%pattern}and friends.
  1. 有一个{失踪后browsefolders ()
  2. $in应该是$suffix
  3. 带有 的行cut只能让您看到 的中间部分front.middle.extension。你应该阅读你的 shell 手册${varname%%pattern}和朋友们。

I assume you do this as an exercise in shell scripting, otherwise the findsolution already proposed is the way to go.

我假设你这样做是作为 shell 脚本的练习,否则find已经提出的解决方案就是要走的路。

To check for proper shell syntax, without running a script, use sh -n scriptname.

要在不运行脚本的情况下检查正确的 shell 语法,请使用sh -n scriptname.

回答by Scott C Wilson

The syntax I use is a bit different than what @Matt suggested:

我使用的语法与@Matt 建议的有点不同:

find $directory -type f -name \*.in

(it's one less keystroke).

(少了一个按键)。

回答by Mohammad AlQanneh

find {directory} -type f -name '*.extension'

Example:To find all csvfiles in the current directory and its sub-directories, use:

示例:要查找csv当前目录及其子目录中的所有文件,请使用:

find . -type f -name '*.csv'

回答by Bharat Yadav

To find all the pom.xmlfiles in your current directory and print them, you can use:

要查找pom.xml当前目录中的所有文件并打印它们,您可以使用:

find . -name 'pom.xml' -print

回答by Sergiu

find $directory -type f -name "*.in"|grep $substring

回答by rtrn

Without using find:

不使用find

du -a $directory | awk '{print }' | grep '\.in$'

回答by Avinash Kumar Mishra

for file in "${LOCATION_VAR}"/*.zip
do
  echo "$file"
done 

回答by Inian

Though using findcommand can be useful here, the shell itself provides options to achieve this requirement without any third party tools. The bashshell provides an extended glob support option using which you can get the file names under recursive paths that match with the extensions you want.

尽管使用find命令在这里很有用,但外壳本身提供了无需任何第三方工具即可实现此要求的选项。该bash外壳提供了使用扩展的水珠支持选项,您可以在递归路径获得的文件名那场比赛你想要的扩展。

The extended option is extglobwhich needs to be set using the shoptoption as below. The options are enabled with the -ssupport and disabled with he -uflag. Additionally you could use couple of options more i.e. nullglobin which an unmatched glob is swept away entirely, replaced with a set of zero words. And globstarthat allows to recurse through all the directories

扩展选项extglob需要使用如下shopt选项进行设置。这些选项通过-ssupport启用,通过 he-u标志禁用。此外,您可以使用更多选项,即nullglob其中一个不匹配的 glob 被完全清除,替换为一组零字。并globstar允许通过的所有目录递归

shopt -s extglob nullglob globstar

Now all you need to do is form the glob expression to include the files of a certain extension which you can do as below. We use an array to populate the glob results because when quoted properly and expanded, the filenames with special characters would remain intact and not get broken due to word-splitting by the shell.

现在您需要做的就是形成 glob 表达式以包含特定扩展名的文件,您可以按如下方式执行。我们使用一个数组来填充 glob 结果,因为当正确引用和扩展时,带有特殊字符的文件名将保持完整,不会由于 shell 的分词而被破坏。

For example to list all the *.csvfiles in the recursive paths

例如列出*.csv递归路径中的所有文件

fileList=(**/*.csv)

The option **is to recurse through the sub-folders and *.csvis glob expansion to include any file of the extensions mentioned. Now for printing the actual files, just do

选项**是通过子文件夹递归,并且*.csv是全局扩展以包含提到的扩展名的任何文件。现在要打印实际文件,只需执行

printf '%s\n' "${fileList[@]}"

Using an array and doing a proper quoted expansion is the right way when used in shell scripts, but for interactive use, you could simply use lswith the glob expression as

在 shell 脚本中使用数组并进行适当的带引号扩展是正确的方法,但对于交互式使用,您可以简单地ls将 glob 表达式用作

ls -1 -- **/*.csv

This could very well be expanded to match multiple files i.e. file ending with multiple extension (i.e. similar to adding multiple flags in findcommand). For example consider a case of needing to get all recursive image files i.e. of extensions *.gif, *.pngand *.jpg, all you need to is

这可以很好地扩展以匹配多个文件,即以多个扩展名结尾的文件(即类似于在find命令中添加多个标志)。例如,考虑需要获取所有递归图像文件即扩展名的情况*.gif*.png并且*.jpg,您需要做的就是

ls -1 -- **/+(*.jpg|*.gif|*.png)

This could very well be expanded to have negate results also. With the same syntax, one could use the results of the glob to exclude files of certain type. Assume you want to exclude file names with the extensions above, you could do

这也可以很好地扩展为否定结果。使用相同的语法,可以使用 glob 的结果来排除某种类型的文件。假设您想排除具有上述扩展名的文件名,您可以这样做

excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"

The construct !()is a negate operation to not include any of the file extensions listed inside and |is an alternation operator just as used in the Extended Regular Expressions library to do an OR match of the globs.

该构造!()是一个否定操作,不包括其中列出的任何文件扩展名,并且|是一个替代运算符,就像在扩展正则表达式库中用于对 glob 进行 OR 匹配一样。

Note that these extended glob support is not available in the POSIX bourne shell and its purely specific to recent versions of bash. So if your are considering portability of the scripts running across POSIX and bashshells, this option wouldn't be right.

请注意,这些扩展的 glob 支持在 POSIX bourne shell 中不可用,并且它完全特定于最新版本的bash. 因此,如果您正在考虑跨 POSIX 和bashshell运行的脚本的可移植性,则此选项不正确。

回答by kip2

find "$PWD" -type f -name "*.in"