问题描述
有没有办法在单个命令中做到这一点?
我使用的是 AIX 7.1。
解决方法
取决于您所说的“单个命令”是什么意思,这是一个不寻常的要求。一般来说,您可以在通配符上使用 find
或 for
循环:
-
带有
find
:find . -type f -exec sh -c 'for f; do [ $(wc -l < "$f") -eq 2 ] && mv -- "$f" /target/dir/; done' findshell {} +
-
带有
for
:for f in ./*; do [ -f "$f" ] && [ $(wc -l < "$f") -eq 2 ] && mv -- "$f" /target/dir; done
如果您有一个文件列表,例如可能带有 ksh93 和一个数组变量 -- files=( * )
-- 您可以遍历这些文件名:
for f in "${files[@]}"; do [ -f "$f" ] && [ $(wc -l < "$f") -eq 2 ] && mv -- "$f" /target/dir; done
在find
解决方案中,我们将结果限制为“文件”类型;对于其中的每一个,我们执行一个带有尽可能多的参数的 shell(语法的 {} +
部分);该shell被赋予'findshell'作为ARG[0],只是作为一个占位符。其余参数在内部 for
循环中检查;移动正好有两行的那些。
在 for
解决方案中,我们遍历结果文件列表并检查以确保我们查看的是常规文件 [ -f "$f" ]
并且该文件正好包含两行。如果这两个条件都匹配,我们就移动文件。
在所有 mv
情况下,我们在给出文件名之前使用 --
显式结束选项,以便以 -
破折号开头的文件名不会无意中被误认为是选项.这也是手动 for
循环使用 ./*
作为通配符的原因,以便所有扩展的文件名都以 ./
开头,从而防止这些文件名以破折号开头。