如何在bash中获取目录列表,然后将它们作为命令行参数展开?

Cha*_*all 9 bash command-line-arguments

我正在编写一个bash脚本,它需要一步获取目标目录(可能还包含文件)中的目录列表(变量),然后将它们作为参数展开到python脚本中.

例:

/stuff/a dir/
/stuff/b other/
/stuff/c/
Run Code Online (Sandbox Code Playgroud)

我需要在bash脚本中调用:

script.py "a dir/" "b other/" "c/"
Run Code Online (Sandbox Code Playgroud)

或者,逃逸的空间:

script.py a\ dir/ b\ other/ c/
Run Code Online (Sandbox Code Playgroud)

我需要为目录'stuff'调用一次脚本.

有没有直接的方法来做这种事情?我一直在谷歌搜索,我已经设法找出最好的,要求我知道有多少目录.

Joh*_*ica 17

这是一项寻找工作.

find /stuff -type d -exec script.py {} +
Run Code Online (Sandbox Code Playgroud)

当您使用-exec花括号时,{}将替换为匹配文件的名称,并+指示命令的结束(如果您想告诉find采取其他操作).这是使用find执行命令的理想方法,因为它将正确处理具有异常字符(如空格)的文件名.

find非常灵活,特别是如果你有通常与Linux发行版捆绑在一起的GNU版本.

# Don't recurse into subdirectories.
find /stuff -maxdepth 1 -type d -exec script.py {} +

# Pass in a/, b/, c/ instead of /stuff/a/, /stuff/b/, /stuff/c/.
find /stuff -type d -printf '%P\0' | xargs -0 script.py
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,请注意小心使用\0xargs -0使用NUL字符来分隔文件名.它可能看起来很奇怪,但即使你做了一些非常奇怪的事情,比如\n在你的目录名中使用换行符,这也可以使命令工作.


或者,您可以仅使用shell内置函数执行此操作.我不推荐这个,但是为了教育价值,这里是如何:

# Start with an empty array.
DIRS=()

# For each file in /stuff/...
for FILE in /stuff/*; do
    # If the file is a directory add it to the array. ("&&" is shorthand for
    # if/then.)
    [[ -d $FILE ]] && DIRS+=("$FILE")

    # (Normally variable expansions should have double quotes to preserve
    # whitespace; thanks to bash magic we don't them inside double brackets.
    # [[ ]] has special parsing rules.)
done

# Pass directories to script. The `"${array[@]}"` syntax is an unfortunately
# verbose way of expanding an array into separate strings. The double quotes
# and the `[@]` ensure that whitespace is preserved correctly.
script.py "${DIRS[@]}"
Run Code Online (Sandbox Code Playgroud)


小智 5

一个不创建新流程(如find那样)的简单解决方案是:

for f in stuff/*; do
  if [ -d "$f" ]; then
     ./script.py "$f"
  fi
done
Run Code Online (Sandbox Code Playgroud)