检查bash中是否存在满足特定条件的目录

时间:2018-04-30 01:39:26

标签: bash shell directory

我试图让bash检查一个目录是否存在,但只有当它符合某个标准时。

例如,我想检查一个以pkg_开头的目录,以及下面的任何其他字符是否存在。

因此,如果存在名为pkg_1.0pkg_2.0的文件夹,bash仍会抓住它。

目前代码看起来像这样:

if [ -d "~/pkg_*" ];

但是每次运行时都会返回false,无论是否存在任何使用pkg_求解的目录

同时,使用cd ~/pkg_*工作正常,我可以cd进入该目录。

4 个答案:

答案 0 :(得分:2)

shopt -s nullglob
for path in ~/pkg_*/
do
    [do what you want if at least one such directory exists]
    break
done

说明:

  • 设置nullglob可确保~/pkg_*/解析为空字符串(如果不存在此类目录),这意味着我们不会进入循环。
  • 尾部斜杠确保我们只匹配目录,而不是普通文件。
  • expand tilde and asterisk您想要的方式,这些字符必须不加引号。如果quoted这些匹配文件名中的 literal 代字号和星号字符,这很可能但非常不寻常。
  • break停止循环,因此条件只运行一次。

示例会话:

$ cd
$ shopt -s nullglob
$ for path in ~/pkg_*/
> do
>     echo 'Found one!'
>     break
> done
$ mkdir 'pkg_a'
$ for path in ~/pkg_*/
> do
>     echo 'Found one!'
>     break
> done
Found one!
$ mkdir 'pkg_b with spaces'
$ for path in ~/pkg_*/
> do
>     echo 'Found one!'
>     break
> done
Found one!

答案 1 :(得分:0)

我真的要看你需要查找目录的位置。如果您只需要检查单个目录中是否有pkg_...个命名目录,那么您可以使用for循环,循环遍历给定目录中的目录,如IObO在其答案中所示。

但是,如果您需要在给定目录下搜索名为pkg_...的目录的所有子目录,则使用find提供了一个方便的选项。在bash中,您可以使用进程替换将符合条件的目录名称提供给while循环,例如

while read -r pkgdir; do
    ## do what you need with "$pkgdir"
done < <(find /path -type d -name "pkg_*")

注意:需要< <之间的空格)

find命令将找到名称与glob -type d匹配的/path下的所有目录"pkg_*"。这些将由while循环读入变量pkgdir。然后,您可以以任何方式处理"$pkgdir"中的目录。

您还可以使用-exec选项查找执行所需的任何单个命令,或者在每个目录上调用另一个脚本。您还可以将结果传递给xargs并完成相同的操作(建议在-print0中使用find输出以空字符结尾的目录名称和-0 xargs选项表示相同)

如果您有任何其他问题,请告诉我。

答案 2 :(得分:-1)

虽然不是优雅的单行,但你可以试试这个:

filelist="$HOME/pkg_*"
for f in $filelist; do
    if [ -d "$f" ]; then
        action_if_true
    fi
done

但是,如果您有多个匹配的文件夹,这会产生多次执行操作的副作用。

BTW,我使用环境变量$ HOME代替第一行中的波浪号,因为波浪号不起作用。

我对此进行了测试,它似乎也适用于经典的Bourne shell。

那里的bash专家可能有更好的答案。

答案 3 :(得分:-1)

你可以这样做。

#!/bin/bash

    fpath=`find ~/ -type d -name "pkg_*"` #which finds all folder start the name pkg_ in the path ~/

对每个文件夹执行单独的操作

for fnd in $fpath
do
    echo "$fnd"
done

要在不同路径中搜索,请根据需要替换~/

修改:如果文件夹名称包含空格,请使用此

#!/bin/bash
  find . -type d | while read fpath; do echo $fpath; done