将目录中的所有文件作为 cli 参数附加

将目录中的所有文件作为 cli 参数附加

我需要运行一个如下所示的命令

mycli --file test.zip --file another_test.zip

我如何才能动态地运行目录中的所有 zip 文件?我确信我可以通过 find 命令传输文件,但我不知道如何将它们作为参数附加到另一个命令中,而且我的 bash-fu 不太好

答案1

使用数组:

unset -v args
declare -a args
for file in *.zip
do
  args+=( --file "$file" )
done
mycli "${args[@]}"

或者,POSIXly:

set --
for file in *.zip
do
  set -- "$@" --file "$file"
done
mycli "$@"

或者,假设使用 GNU 工具:

find . -maxdepth 1 -name '*.zip' -printf '--file\0%f\0' |
  xargs -0 -- mycli

基于数组的方法和xargs基于数组的方法之间的相关区别:虽然前者可能会失败并出现“参数列表太长”错误(假设mycli不是内置命令),后者不会,并且会运行mycli多次。但请注意,在最后一种情况下,除了最后一次调用的参数列表之外的所有参数列表都可能以--file(并且以下参数列表以文件名开头)结尾。根据您的使用情况,您也许可以使用xargs' 选项的组合(例如-n-x)来防止这种情况发生。

另请注意,find将包括隐藏文件在其输出中,而基于数组的替代方案则不会,除非dotglob在 Bash 中设置了 shell 选项,或者在 POSIX shell 中同时使用了*.zip和globbing 表达式。.*.zip有关详细信息和注意事项: 如何将所有文件(包括隐藏文件)从一个目录移动到另一个目录?

答案2

假设您没有数千个文件(这会生成“参数列表太长”错误),那么您可以使用 shell 执行以下操作zsh

mycli ./*.zip(P:--file:)

或者,从bash外壳:

zsh -c 'exec mycli ./*.zip(P:--file:)'

(我exec在这里使用进程来替换zshshell mycli,以提高效率。)

文件P名 globbing 限定符将给定字符串(此处为--file)作为单独的单词添加到 glob 扩展到的每个元素之前。

要包含隐藏文件,请添加Dbefore P,并将匹配限制为仅常规文件,请添加.

zsh -c 'exec mycli ./*.zip(.DP:--file:)'

对于递归到子目录:

zsh -c 'exec mycli ./**/*.zip(.DP:--file:)'

...并按照修改时间戳的顺序对文件进行排序(您愿意这样做),请om按照您添加的方式D.之前的方式添加。

答案3

这有效:

ls *.zip | xargs printf "--file %s " | xargs echo mycli

一旦您对结果命令感到满意,请删除echo第二个命令xargs并重新运行。

如果您的 zip 文件的名称包含空格或其他 shell 元字符,则情况会变得更加复杂。

相关内容