我需要运行一个如下所示的命令
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
在这里使用进程来替换zsh
shell mycli
,以提高效率。)
文件P
名 globbing 限定符将给定字符串(此处为--file
)作为单独的单词添加到 glob 扩展到的每个元素之前。
要包含隐藏文件,请添加D
before 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 元字符,则情况会变得更加复杂。