如何在xargs中同时使用-I与-n参数?
解决xargs同时分组与批量移动文件的问题
当然可以!这里有两种实用的方法,不需要GNU Parallel就能实现你想要的分组批量移动效果,完美避开-I和-n的冲突问题:
方法1:利用mv -t简化命令(推荐)
如果你的系统使用的是GNU coreutils(大部分Linux发行版默认都是),mv命令支持-t选项——它可以直接指定目标目录,这样就不需要用-I来占位替换了。xargs会自动将find找到的文件分组传递给mv,完全不会触发参数数量超限的问题:
find /foo -name 'bar*' | xargs mv -t /dest
这个命令的效果是,xargs会把一批文件作为参数传给mv(具体数量由系统参数限制自动调整),执行mv 文件名1 文件名2 ... /dest,既高效又简洁。
方法2:用Shell脚本包裹实现分组(兼容旧系统)
如果你的mv不支持-t选项(比如某些BSD系统),可以用bash -c来包裹mv命令,让xargs把分组后的文件传递给shell执行:
find /foo -name 'bar*' | xargs -n 100 bash -c 'mv "$@" /dest' _
细节解释:
-n 100:指定每次传递100个文件给后续命令(你可以根据需要调整这个数字);bash -c 'mv "$@" /dest':执行后面的shell命令,"$@"代表所有传入的文件参数;- 最后的
_:是bash的$0占位符(因为bash -c的第一个参数会被当作脚本名称,$@从$1开始),只是用来填充位置,不影响实际功能。
用你的测试例子验证效果:
echo {0..9} | xargs -n 3 bash -c 'echo mv "$@" /dest' _
输出结果完全符合你的预期:
mv 0 1 2 /dest mv 3 4 5 /dest mv 6 7 8 /dest mv 9 /dest
为什么-I和-n不能同时用?
你提到的-I参数确实会隐含-L 1,这意味着xargs会逐行处理输入,每次只替换一个占位符,所以-n的分组效果会被完全覆盖,导致所有文件都被一次性替换到占位符位置,这就是为什么你之前的测试没有得到分组结果的原因。
内容的提问来源于stack exchange,提问作者Wilfred Hughes
相关产品推荐
相关产品推荐

