【问题标题】:Bash checking for foldername using substringBash 使用子字符串检查文件夹名称
【发布时间】:2016-02-24 00:53:23
【问题描述】:

我需要一些关于 bash 脚本的帮助。

脚本应该以“数据库风格”的方式工作。

我需要

  • 添加客户,将获得客户编号
  • 为每个新客户创建一个文件夹(如果我从目录运行程序 /company/myprogram 每个新客户将在该目录中拥有他自己的文件夹

当我启动程序时,我希望它向我询问客户编号。

如果客户是新客户,程序将询问他的凭据,并在提供凭据后,将通过创建一个名为“'customer-number''surname'”的新文件夹来创建客户,即 15112101 Doe.

如果客户已经存在,它应该显示一条消息“客户已经存在”并转到该客户。

现在问题来了。我已经尝试过使用类似的东西 字符串="15112101"

if [[ ! -d "$string" ]]; then
 echo "No such customer"
else 
 cd "$string"

但是如何确定当前目录是否包含以该客户编号开始的文件夹,如果为真,则 cd 到该文件夹​​。如果为 false,则新建客户。

即1) 文件夹 15112101 Doe 存在于 /company/myprogram

启动程序 > 询问客户编号 > 插入 15112101 > 输出应该是: 找到客户 15112101 Doe,前往 /company/myprogram/15112101 Doe

即2) /company/myprogram 中不存在文件夹 15112101 Doe

启动程序 > 询问客户编号 > 插入 15112101 > 输出应该是:客户不存在,创建新的?

【问题讨论】:

    标签: bash grep directory ls


    【解决方案1】:

    试试这个(${string}*是以$string开头的目录名)

    if [[ ! $(find . -type d -name ${string}*) ]]; then
     echo "No such customer"
    else 
     cd "$string"
    

    编辑: 修复

    1 fi 不见了

    if [[ ! $(find . -type d -name ${string}*) ]]; then
      echo "Customer does not exist, create new?"
     else 
      cd $string
     fi
    

    2 ${string}* 中的星号需要转义

    if [[ ! $(find . -type d -name ${string}\*) ]]; then
     echo "Customer does not exist, create new?"
    else 
     cd $string
    fi
    

    3如果有多个以$string开头的目录,那么cd $string这个命令没有意义,你需要决定在这种情况下怎么做

    if [[ ! $(find . -type d -name ${string}\*) ]]; then
     echo "Customer does not exist, create new?"
    else 
     echo "found customers " $(ls ${string}*);
    fi
    

    4如果您有嵌套目录并且想要从搜索中排除它们,您需要使用-maxdepth 1

    if [[ ! $(find . -maxdepth 1 -type d -name ${string}\*) ]]; then
     echo "Customer does not exist, create new?"
    else 
     echo "found customers " $(find . -maxdepth 1 -type d -name ${string}\*);
    fi
    

    5 删除双重find

    cust=$(find . -maxdepth 1 -type d -name ${string}\*)
    if [[ ! $cust ]]; then
     echo "Customer does not exist, create new?"
    else 
     echo "found customers " $cust;
    fi
    

    【讨论】:

    • 感谢您的快速回复,这有效!唯一我仍然需要帮助的是 cd "$string" 部分。如果文件夹名为 15112101 Doe,则表示 $string 的值为 15112101(这不是我需要转到的文件夹名称。我需要 15112101 Doe)
    • 没关系,通过将你的行变成一个变量然后 cd'ing 到所述变量来修复它。再次感谢!
    • 除了${string}* 需要被引用之外,如果有多个以$string 开头的目录,或者找到的唯一目录包含空格,这将中断。
    • 您的if 语句缺少结束语fi
    【解决方案2】:

    user2314737的回答有几个问题:

    1. 不考虑子目录中是否有带有该前缀的目录。 Find 应设置为 -depth 1 以省略它们。

    2. 不考虑有多个目录具有该前缀的情况。问题没有说明这种情况是否可能,但应该考虑。

    3. 无需使用[[[ 更便携。

    4. 在找到目录的情况下,最后的cd 执行时没有结尾* 的glob。这将失败,因为$string 是前缀,而不是目录的完整名称。

    解决上述问题,我提出以下解决方案:

    PREFIX=123
    COUNT=`find . -type d -maxdepth 1 -name "${PREFIX}*" | wc -l`
    if [ $COUNT = "1" ]; then
      echo "There is one and only one directory with prefix $PREFIX"
      cd "${prefix}*"
      pwd
    else
      echo "$COUNT directories with prefix $PREFIX"
    fi 
    

    【讨论】:

    • -depth 1 很可能无效。 -depth 只是告诉find 以深度优先方式进行的谓词。在这里肯定不会有帮助。
    【解决方案3】:

    您需要遍历文件夹中的所有目录:

    shopt -s nullglob
    customer_dir=
    for d in /company/program/"$string "*/; do
        if [[ -n $customer_dir ]]; then
            echo "Found a second matching dir: $d and $customer_dir"
            # Handle error here
        fi
        customer_dir=$d
    done
    if [[ -z $customer_dir ]]; then
        echo "No such customer $string; create?"
    fi
    

    这涵盖了几种情况:nullglob 防止在没有匹配项时进入循环,因此customer_dir 永远不会被设置。理想情况下,glob 将匹配 0 或 1 目录,但为了完全安全,它会检测是否找到第二个匹配项。 (这种情况下怎么办,我交给你了。)

    【讨论】:

    • 你应该引用扩展 $string (除非用户真的想在这里使用 glob)。另外,你有什么不使用for d in "/company/program/$string"*/; do的原因吗?
    • 第一部分是正确的,第二部分是我提交答案几分钟后想到的。
    猜你喜欢
    • 2013-04-26
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2019-11-11
    • 2017-08-21
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多