【问题标题】:Globbing for only files in Bash仅在 Bash 中查找文件
【发布时间】:2013-12-23 14:36:36
【问题描述】:

我在 Bash 中遇到了一些问题。例如:

echo *

这会打印出当前目录中的所有文件和文件夹。 例如(文件1 文件2 文件夹1 文件夹2)

echo */

这会打印出名称后带有 / 的所有文件夹。 例如(文件夹1/文件夹2/)

我怎样才能只获取文件? 例如(文件1文件2)

我知道可以通过解析 ls 来完成,但也知道 it is a bad idea。我尝试使用扩展 blob,但也无法正常工作。

【问题讨论】:

    标签: bash glob


    【解决方案1】:

    不使用任何外部实用程序,您可以尝试for loopglob support

    for i in *; do [ -f "$i" ] && echo "$i"; done
    

    【讨论】:

    • 这看起来正是我的想法。非常感谢你。我不确定我是否完全理解它。它是否遍历 glob 并且 [-f "$i"] 正在测试它是否是一个文件?编辑:刚刚检查了手册页进行测试。再次感谢!
    • @JohnP,是的。您还可以使用[ ! -d "$i" ] 来测试当前项目是否不是目录 -- 然后您将包括符号链接和其他类型的文件,只是明确地不是目录。
    • 没错! For 循环迭代当前目录中的每个条目,[ -f "$i" ] 检查该条目是否为常规文件。
    • (!) test -f 仅测试普通(常规)文件,不检查块特殊文件(如 /dev/null)、套接字、符号链接 [..]。
    【解决方案2】:

    我不知道你是否可以用通配符解决这个问题,但你当然可以用find 解决它:

    find . -type f -maxdepth 1
    

    【讨论】:

    • 最干净,尤其是在 args 中用于其他一些命令时,例如perl -pi -e 's/foo/bar/g' $(find . -maxdepth 1 -type f)。哦,次要的事情:maxdepth 必须首先出现以避免警告:“您在非选项参数 -type (...) 之后指定了 -maxdepth 选项”
    【解决方案3】:

    你可以像这样在 bash 中做你想做的事:

    shopt -s extglob
    echo !(*/)
    

    但请注意,这实际上是匹配“不是目录喜欢”。
    它仍然会匹配悬空符号链接、指向非目录的符号链接、设备节点、fifos 等。

    但它不会匹配指向目录的符号链接。

    如果您只想遍历普通文件,仅此而已,请使用find -maxdepth 1 -type f

    安全可靠的使用方式如下:

    find -maxdepth 1 -type f -print0 | while read -d $'\0' file; do
      printf "%s\n" "$file"
    done
    

    【讨论】:

    • 您的 bash-only 解决方案与我的 echo * 完全相同
    • 同样要激活 extglob 选项,您必须使用 shopt -s extglob,因为 shopt extglob 仅在设置选项时显示。
    • 支持使用 find 的安全方式,请注意 extglob 解决方案不起作用,至少在 bash 5 中不起作用。
    【解决方案4】:

    在这种情况下,我会使用find 命令。我只需要使用它来查找/替换给定目录中的数十个实例。我敢肯定还有很多其他方法可以给这只猫剥皮,但上面的纯 for 示例不是递归的。

    for file in $( find path/to/dir -type f -name '*.js' );
        do sed -ie 's#FIND#REPLACEMENT#g' "$file";
        done
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 2017-10-18
      • 2018-04-08
      • 1970-01-01
      相关资源
      最近更新 更多