答案1
查看 zsh 文档的最佳方法是使用info
.
如果你运行info zsh
,你可以使用指数(想一个书的索引)来定位描述该命令的部分zmodload
。
按i,即可输入zmo
并按Tab。您将直接进入zmodload
内置描述,它会告诉您所有相关信息。
简而言之,zmodload -F
加载模块(如果未加载)并仅启用指定的特征从该模块。
通过,我们在此处启用了匹配模式-m
的功能。是针对内置的,因此上面的命令加载模块(有关详细信息,请参阅 参考资料)并且仅启用名称以.mb:zf_*
b:
zsh/files
info -f zsh -n 'The zsh/files Module,'
zf_
zmodload -F zsh/files
加载模块,但不启用任何功能:
$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync -b:zf_chgrp -b:zf_chown -b:zf_ln -b:zf_mkdir -b:zf_mv -b:zf_rm -b:zf_rmdir -b:zf_sync
列出该模块的功能,指定当前启用的功能(目前没有)。您会注意到有 amv
和zf_mv
内置的。
$ zmodload -mF zsh/files 'b:zf_*'
$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync +b:zf_chgrp +b:zf_chown +b:zf_ln +b:zf_mkdir +b:zf_mv +b:zf_rm +b:zf_rmdir +b:zf_sync
您会注意到zf_mv
内置函数已启用,但不是那个内置mv
函数(其他内置函数也是如此)。这意味着,这些内置版本的系统命令已启用,但不会覆盖系统命令:
$ type zf_mv
zf_mv is a shell builtin
$ type mv
mv is /bin/mv
现在你已经有了一个内置的mv
,作为zf_mv
,不是mv
,你可以这样做:
zf_mv -- ^*.(jpg|png|bmp) targetdir/
因为zf_mv
它是内置的,所以没有execve()
系统调用,所以您不会达到Too many args
与其相关的限制。
当然,你也可以这样做:
zmodload zsh/files # without -F, all the features are enabled
mv -- ^*.(jpg|png|bmp) targetdir/
mv
但请注意,它会用内置的等效项替换系统zsh
。
为了克服E2BIG
execve()
错误(参数过多执行外部命令时),zsh
还提供了一个zargs
功能。
你跑:
autoload zargs # in ~/.zshrc if you use it often
将其标记为自动加载。
然后你可以使用:
zargs -- ^*.(jpg|png|bmp) -- mv -t targetdir/
(这里假设 GNUmv
作为-t
选项)。zargs
将运行mv
尽可能多的命令以避免 E2BIG(就像xargs
会做的那样)。
答案2
有一个不依赖 bashism 的通用解决方案:xargs
。
xargs
从中读取参数流stdin
,然后将它们传递给任意指定的实用程序。在你的情况下,命令行应该是这样的:
# find -E /source/dir -iregex ".*\.(jpg|png|bmp)" | xargz -n 1 -J % mv % /target/dir
这里-E
意味着find
使用现代正则表达式(for|alternatives),-n 1
意味着传入流将被分割成单个参数,-J %
意味着每个参数将在%
字符的下一次出现时被替换。
-J %
是必要的,因为xargs
默认情况下将参数附加到子命令的末尾。缺少-J %
就相当于xargs -n 1 -J % mv /target/dir %
那绝对不是你想要的。