我正在尝试使用我的bash(最新的Ubuntu LTS版本)在目录及其子目录中查找具有特定扩展名的所有文件。
这是在脚本文件中写的:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
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"
不幸的是,当我在终端中启动这个脚本时,它说:
[: 29: in: unexpected operator
(使用$extension
而不是'in'
)
这里发生了什么,错误在哪里? 但是这个大括号
find {directory} -type f -name '*.extension'
示例 查找当前目录及其子目录中的所有csv文件
find . -type f -name '*.csv'
要查找当前目录中的所有pom.xml
文件并打印它们,您可以使用:
find . -name 'pom.xml' -print
find $directory -type f -name "*.in"|grep $substring
不使用find
:
du -a $directory | awk '{print $2}' | grep '\.in$'
for file in "${LOCATION_VAR}"/*.zip
do
echo "$file"
done
虽然使用find
命令在这里很有用,但shell本身提供了在没有任何第三方工具的情况下实现此要求的选项。 bash
shell提供了一个扩展的glob支持选项,使用该选项可以在与所需扩展名匹配的递归路径下获取文件名。
扩展选项是extglob
,需要使用shopt
选项进行设置,如下所示。 使用-s
标志启用选项,使用he -u
标志禁用选项。 另外你可以使用更多的选项,即nullglob
,其中一个不匹配的glob被完全扫除,用一组零个单词替换。 并且globstar
允许递归所有目录
shopt -s extglob nullglob globstar
现在您需要做的就是形成glob表达式以包含某个扩展名的文件,您可以执行以下操作。 我们使用数组来填充glob结果,因为当正确引用并扩展时,具有特殊字符的文件名将保持不变,并且不会因shell的分词而被破坏。
例如,列出递归路径中的所有*.csv
文件
fileList=(**/*.csv)
选项**
是通过子文件夹递归, *.csv
是glob扩展,包括所提到的扩展的任何文件。 现在打印实际文件,就行了
printf '%s\n' "${fileList[@]}"
在shell脚本中使用数组并进行适当的引用扩展是正确的方法,但是为了交互式使用,您可以简单地将ls
与glob表达式一起使用
ls -1 -- **/*.csv
这可以很好地扩展以匹配多个文件,即以多个扩展名结尾的文件(即类似于在find
命令中添加多个标志)。 例如,考虑需要获取所有递归图像文件的情况,即扩展*.gif
, *.png
和*.jpg
,您需要的只是
ls -1 -- **/+(*.jpg|*.gif|*.png)
这很可能会扩大到取消结果。 使用相同的语法,可以使用glob的结果来排除某种类型的文件。 假设你想要用上面的扩展名排除文件名,你可以这样做
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
构造!()
是一个否定操作,不包括里面列出的任何文件扩展名和|
是一个交替运算符,就像在扩展正则表达式库中一样,用于对全局进行OR匹配。
请注意,这些扩展的glob支持在POSIX bourne shell中不可用,并且完全特定于最新版本的bash
。 因此,如果您正在考虑跨POSIX和bash
shell运行的脚本的可移植性,则此选项不正确。
find "$PWD" -type f -name "*.in"
find $directory -type f -name "*.in"
比整个事情要短一些(更安全 - 处理文件名和目录名中的空格)。
您的脚本可能无法使用没有的条目.
在他们的名字,使$extension
空。
browsefolders ()
之后有一个{
丢失 $in
应该是$suffix
cut
的线只能获得front.middle.extension
的中间部分。 您应该阅读${varname%%pattern}
和朋友的shell手册。 我假设您将此作为shell脚本中的练习,否则已经提出的find
解决方案是可行的方法。
要在不运行脚本的情况下检查正确的shell语法,请使用sh -n scriptname
。
我使用的语法与@Matt建议的有点不同:
find $directory -type f -name \*.in
(这是一个较少的击键)。