当没有文件匹配时,如何删除 find 的标准输出中的 null 值?
Vformat=(mp4 wmv pgep mov)
for File in ${Vformat[@]}
do
find $SrcDir -iname "*.$File" | xargs ls -l --time-style=full-iso
done
答案1
从你的问题中,我猜你真正想问的是“当 xargs 的标准输入为空时如何阻止其运行”因此它ls
永远不会在没有参数的情况下运行(它会列出当前目录中的文件)。
GNUxargs
对此有一个选项;来自man xargs
:
-r, --no-run-if-empty If the standard input does not contain any nonblanks, do not run the command. Normally, the command is run once even if there is no input. This option is a GNU extension.
然而GNU还提供了一种机制,在大多数情况下find
避免将其输出通过管道传输到- 来自:xargs
man find
-exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca‐ tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines.
例如你可以这样做
Vformat=(mp4 wmv pgep mov)
for File in "${Vformat[@]}"
do
find "$SrcDir" -iname "*.$File" -exec ls -l --time-style=full-iso {} +
done
如果您想避免多次调用的开销find
,那么一种方法是将扩展数组转换为-iname xxx
通过-o
逻辑或连接连接的参数数组:
Vformat=(mp4 wmv pgep mov)
args=()
for File in "${Vformat[@]}"
do
args+=( -o -iname "*.$File" )
done
进而
find "$SrcDir" -type f \( "${args[@]:1}" \) -exec ls -l --time-style=full-iso {} +
数组切片${args[@]:1}
删除了前导-o
和文字括号\(
,并对\)
OR 列表进行分组,因为-exec
具有 AND 优先级。
最后,如果您只需要文件名和修改时间,那么您可以考虑使用find
命令-printf
而不是外部命令ls
:
find "$SrcDir" -type f \( "${args[@]:1}" \) -printf '%TF %TT %Tz\t%p\n'
答案2
提高你的发现能力。重新阅读man find
,并做类似下面的事情** 未经测试 **:
Vformat=(mp4 wmv pgep mov)
find "$SrcDir" -type f \
\( -iname '*.mp4' -o \
\( -iname '*.wmv' -o \
\( -iname '*.pgep' -o \
\( -iname '*.mov' \
\) \
\) \
\) \
\) \
-print0 | \
xargs -0 --no-run-if-empty \
ls -l --time-style=full-iso
以下是简要概述:
- 反斜杠会反转下一个字符“
\
换行符”的“特殊性”,该字符将被视为空格,\(
并且\)
对于 来说是“特殊的”find
,并且用于对表达式进行分组。 "$SrcDir"
始终引用变量-type f
我们只关心文件。'*.mp4'
使用单引号来延迟 shell 的扩展- 通过将所有
-iname
测试与-o
(find
“OR”)结合起来,您只需通过一次“$SrcDir”,而不是四次。 -print0
每个文件名都以 ASCII 分隔(与 一起,文件名中禁止使用NUL
字符)。这样您就可以处理带有空格和其他奇怪字符的文件名。/
xargs -0
接受NUL
分隔的文件名列表。--no-run-if-empty
如果生成的参数列表不包含文件名则不要执行(以防find
最后输出垃圾)。
生成find
命令Vformat
尚未完成。提示:使用 2 个变量,一个用于累积“ \( -iname '*.foo' -o
”部分,另一个用于累积“) ”部分。