解析`find`命令

Ent*_*ton 2 command-line find shell-script

以下命令告诉我 mp4 视频文件的长度:

find -type f -name "*.mp4" -print0 | \
   xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null | \
   perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1) && printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60' | \
   tail -n 1
Run Code Online (Sandbox Code Playgroud)

有人可以解析它并解释为什么它是这样的吗?

知道如何在不重新键入或通过复制粘贴的情况下一次又一次地使用它也会很有帮助。

bon*_*ing 12

find -type f -name "*.mp4" -print0
Run Code Online (Sandbox Code Playgroud)

递归搜索当前目录以查找名称以普通文件结尾的文件,.mp4并打印它们的相对路径名,以空字节分隔。-print0-print这里更安全,因为换行符是文件名中的有效字符。查找(1)

| xargs -0
Run Code Online (Sandbox Code Playgroud)

使用输入作为下一个命令的参数。输入是空分隔的。xargs(1)

mplayer -vo dummy -ao dummy -identify 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

这是xargs正在运行的命令。使用虚拟视频和音频驱动程序,以易于解析的格式显示文件参数。丢弃来自 STDERR 的任何输出。播放器(1)

| perl -nle
Run Code Online (Sandbox Code Playgroud)

将输出通过管道传送到 Perl。Perl 会将输入行读取到$_变量中,从末尾去除换行符。perlrun(1)

/ID_LENGTH=([0-9\.]+)/
Run Code Online (Sandbox Code Playgroud)

如果该行与此正则表达式匹配,则捕获“ID_LENGTH=”后面的数字,

&& ($t +=$1)
Run Code Online (Sandbox Code Playgroud)

然后$t通过在第一场比赛中捕获的数字增加变量,

&& printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60'
Run Code Online (Sandbox Code Playgroud)

并从 计算小时、分钟和秒$t,这是秒计数。由于-l在 perl 调用中,会自动向print语句添加换行符,而不是printf,因此格式字符串包含一个(“\n”)。

| tail -n 1
Run Code Online (Sandbox Code Playgroud)

只打印输出的最后一行。尾巴(1)

要将这个管道变成单个命令,您可以在您的.bashrc或您的 shell 使用的任何 rc 文件中创建一个 shell 函数。下面是一个例子:

vid_lengths() {
  find -type f -name "*.mp4" -print0 \
    | xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null \
    | perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1) && printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60' \
    | tail -n 1
}
Run Code Online (Sandbox Code Playgroud)