代码之家  ›  专栏  ›  技术社区  ›  Red Riding Hood

从目录名中提取管道基名时,目录丢失

  •  0
  • Red Riding Hood  · 技术社区  · 7 月前

    给定文件夹结构

    /recipes/foo/.env
    /recipes/bar/.env
    

    运行以下命令:

    find ./recipes -type f -name '.env' -print0 | xargs -0 dirname | xargs -0 basename
    
    Output:
    foo
    

    将命令精简为:

    find ./recipes -type f -name '.env' -print0 | xargs -0 dirname
    
    Output:
    ./recipes/bar
    ./recipes/foo
    

    因此,由于某种原因,将dirname管道连接到basename会导致我丢失一些找到的目录。

    1 回复  |  直到 7 月前
        1
  •  2
  •   Renaud Pacalet    7 月前

    这里有两个问题:

    1. 这个 -0 选项 xargs 表明 输入 NUL是分开的,而不是 输出 .为了管道输出 xargs -0 dirname xargs -0 something 您必须使用 -z 选项 dirname 如果它受支持(它不是POSIX)。否则,其输出以换行符分隔。

    2. basename 默认情况下不支持多个参数。如果你的支持它(它不是POSIX),你可以试试 -a --multiple .

      find ./recipes -type f -name '.env' -print0 |
        xargs -0 dirname -z | xargs -0 basename -a
      

      否则,请使用 -n1 选项 参数代换 :

      find ./recipes -type f -name '.env' -print0 |
        xargs -0 dirname -z | xargs -0 -n1 basename
      

    注:作为你的 find 显然是GNU 找到 你可以跳过 目录名 与:

    find ./recipes -type f -name '.env' -printf '%h\0' | xargs -0 basename -a
    

    注意:您也可以仅使用 找到 以及任何POSIX shell:

    find ./recipes -type f -name '.env' -exec sh -c '
    d="${1%/*}"; printf "%s\n" "${d##*/}"' _ {} \;
    

    注意:如果,如您所示的示例 .env 你不需要的文件有2个 找到 , 参数代换 , 目录名 基名 .你的(POSIX)shell就足够了(加上 printf 实用程序(如果它还不是shell的内置程序):

    for f in recipes/*; do [ -f "$f/.env" ] && printf '%s\n' "${f##*/}"; done