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

我正在尝试使用我的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'

这里发生了什么,错误在哪里? 但是这个大括号


#1楼

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

示例 查找当前目录及其子目录中的所有csv文件

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

#2楼

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

find . -name 'pom.xml' -print

#3楼

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

#4楼

不使用find

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

#5楼

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

#6楼

虽然使用find命令在这里很有用,但shell本身提供了在没有任何第三方工具的情况下实现此要求的选项。 bash shell提供了一个扩展的glob支持选项,使用该选项可以在与所需扩展名匹配的递归路径下获取文件名。

扩展选项是extglob ,需要使用shopt选项进行设置,如下所示。 使用-s标志启用选项,使用he -u标志禁用选项。 另外你可以使用更多的选项,即nullglob ,其中一个不匹配的glob被完全扫除,用一组零个单词替换。 并且globstar允许递归所有目录

shopt -s extglob nullglob globstar

现在您需要做的就是形成glob表达式以包含某个扩展名的文件,您可以执行以下操作。 我们使用数组来填充glob结果,因为当正确引用并扩展时,具有特殊字符的文件名将保持不变,并且不会因s​​hell的分词而被破坏。

例如,列出递归路径中的所有*.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运行的脚本的可移植性,则此选项不正确。


#7楼

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

#8楼

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

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

您的脚本可能无法使用没有的条目. 在他们的名字,使$extension空。


#9楼

  1. 浏览文件browsefolders ()之后有一个{丢失
  2. 所有$in应该是$suffix
  3. cut的线只能获得front.middle.extension的中间部分。 您应该阅读${varname%%pattern}和朋友的shell手册。

我假设您将此作为shell脚本中的练习,否则已经提出的find解决方案是可行的方法。

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


#10楼

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

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

(这是一个较少的击键)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值