递归查找具有特定扩展名的文件
声明:本页面是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
Recursively look for files with a specific extension
提问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 $extension
instead 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 $extension
empty.
对于.
名称中没有 a 的条目,您的脚本可能会失败,从而为$extension
空。
回答by Jens
- There's a
{
missing afterbrowsefolders ()
- All
$in
should be$suffix
- The line with
cut
gets you only the middle part offront.middle.extension
. You should read up your shell manual on${varname%%pattern}
and friends.
- 有一个
{
失踪后browsefolders ()
- 都
$in
应该是$suffix
- 带有 的行
cut
只能让您看到 的中间部分front.middle.extension
。你应该阅读你的 shell 手册${varname%%pattern}
和朋友们。
I assume you do this as an exercise in shell scripting, otherwise the find
solution 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 csv
files in the current directory and its sub-directories, use:
示例:要查找csv
当前目录及其子目录中的所有文件,请使用:
find . -type f -name '*.csv'
回答by Bharat Yadav
To find all the pom.xml
files 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 find
command can be useful here, the shell itself provides options to achieve this requirement without any third party tools. The bash
shell 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 extglob
which needs to be set using the shopt
option as below. The options are enabled with the -s
support and disabled with he -u
flag. Additionally you could use couple of options more i.e. nullglob
in which an unmatched glob is swept away entirely, replaced with a set of zero words. And globstar
that allows to recurse through all the directories
扩展选项extglob
需要使用如下shopt
选项进行设置。这些选项通过-s
support启用,通过 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 *.csv
files in the recursive paths
例如列出*.csv
递归路径中的所有文件
fileList=(**/*.csv)
The option **
is to recurse through the sub-folders and *.csv
is 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 ls
with 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 find
command). For example consider a case of needing to get all recursive image files i.e. of extensions *.gif
, *.png
and *.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 bash
shells, this option wouldn't be right.
请注意,这些扩展的 glob 支持在 POSIX bourne shell 中不可用,并且它完全特定于最新版本的bash
. 因此,如果您正在考虑跨 POSIX 和bash
shell运行的脚本的可移植性,则此选项不正确。
回答by kip2
find "$PWD" -type f -name "*.in"