我正在尝试使用我的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'
)
这里发生了什么,哪里出错? 但是这个大括号
答案 0 :(得分:654)
find $directory -type f -name "*.in"
比整个事情要短一些(更安全 - 处理文件名和目录名中的空格)。
对于名称中没有.
的条目,$extension
为空,您的脚本可能会失败。
答案 1 :(得分:148)
find {directory} -type f -name '*.extension'
示例强> 查找当前目录及其子目录中的所有csv文件
find . -type f -name '*.csv'
答案 2 :(得分:58)
我使用的语法与@Matt建议的语法略有不同:
find $directory -type f -name \*.in
(这是一次击键次数。)
答案 3 :(得分:12)
不使用find
:
du -a $directory | awk '{print $2}' | grep '\.in$'
答案 4 :(得分:10)
{
browsefolders ()
$in
应为$suffix
cut
行只会让您front.middle.extension
的中间部分。您应该阅读${varname%%pattern}
和朋友们的shell手册。我假设您将此作为shell脚本编写的练习,否则已提出的find
解决方案是可行的方法。
要检查正确的shell语法,而不运行脚本,请使用sh -n scriptname
。
答案 5 :(得分:6)
要查找当前目录中的所有pom.xml
文件并打印它们,您可以使用:
find . -name 'pom.xml' -print
答案 6 :(得分:3)
尽管在这里使用find
命令很有用,但是shell本身提供了实现此要求的选项,而无需任何第三方工具。 bash
外壳程序提供了扩展的glob支持选项,通过该选项,您可以在与所需扩展名匹配的递归路径下获取文件名。
扩展选项为extglob
,需要使用shopt
选项进行设置,如下所示。这些选项在-s
支持下启用,在-u
标志下禁用。另外,您可以使用更多选项,例如nullglob
,其中不匹配的glob会被完全清除,而用一组零个单词代替。并且globstar
允许遍历所有目录
shopt -s extglob nullglob globstar
现在,您所需要做的就是形成glob表达式,以包含某个扩展名的文件,您可以按以下方式进行操作。我们使用数组来填充全局结果,因为当正确地引用和扩展它们时,带有特殊字符的文件名将保持不变,并且不会由于shell的单词拆分而损坏。
例如,列出递归路径中的所有*.csv
文件
fileList=(**/*.csv)
选项**
是通过子文件夹递归的,而*.csv
是全局扩展,以包括上述扩展的任何文件。现在要打印实际文件,只需执行
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[@]}"
结构!()
是一个否定运算,不包括内部列出的任何文件扩展名,而|
是一个交替运算符,正如在Extended Regular Expressions库中用来对小球。
请注意,这些扩展的glob支持在POSIX bourne shell中不可用,其纯粹针对bash
的最新版本。因此,如果您正在考虑跨POSIX和bash
shell运行的脚本的可移植性,则此选项不合适。
答案 7 :(得分:1)
find $directory -type f -name "*.in"|grep $substring
答案 8 :(得分:1)
for file in "${LOCATION_VAR}"/*.zip
do
echo "$file"
done
答案 9 :(得分:0)
os.system('apt install program etc...')