【问题标题】:xargs - multiple commands and rm at the endxargs - 多个命令和 rm 最后
【发布时间】:2012-07-19 13:50:58
【问题描述】:

我正在尝试删除我之前正在处理的文件,但它不允许我这样做,请帮助。这是我运行的命令:

find . -type f -name '*.flac' -print0 |
  xargs -0i ffmpeg -i {} -acodec libmp3lame -ab 320k "{}.mp3" |
  rm -rf {}

【问题讨论】:

    标签: shell find xargs


    【解决方案1】:

    如果您安装了 GNU Parallel,您可以这样做:

    find . -type f -name '*.flac' | parallel ffmpeg -i {} -acodec libmp3lame -ab 320k {.}.mp3 '&&' rm {}
    

    它将为每个 CPU 核心运行一个 ffmpeg 进程。

    要了解更多信息,请观看介绍视频:http://pi.dk/1

    【讨论】:

    • 嗨,我想我可能要试试这个。我有一个 3.2GHz 四核 Xeon E3-1230 CPU,Passmark CPU 分数为 8,200,32GB 内存 - 我不能在不超载的情况下执行超过 4 个 ffmpeg 命令......不知道为什么......我可能不得不如果您告诉我我可以让每个 ffmpeg 会话在其自己的 cpu 内核上运行,请考虑这一点。
    • 不确定您所说的“重载”是什么意思。 GNU Parallel 很可能会检测到 8 个内核(因为超线程)并并行启动 8 个 ffmpeg 作业。 GNU Parallel 不保证进程将在其自己的核心上运行。它只是启动与核心数量相对应的作业数量。其余的由您的操作系统负责。
    • 我对其进行了调整并像这样运行它,效果很好!:find . -type f -name '*' |并行 ffmpeg -i {} -sameq {.}.mp4 '&&' rm {}
    • 所以如果我完全理解这一点。这是否意味着我可以做一个 |并并行运行我想要的另一个命令?例如,如果我想将最近编码的文件上传到 ftp 服务器,我将如何用一行来做到这一点?
    • 类似(upload 是您用来上传的程序):find . -type f -name '*.flac' | parallel ffmpeg -i {} -sameq {.}.mp4 '&&' upload {.}.mp4 '&&' rm {}
    【解决方案2】:

    您正在将ffmpeg 调用的输出通过管道传输到rm 命令中。由于ffmpeg 不会产生任何有趣的输出,而rm 不会读取任何输入,因此它不会执行任何操作。

    我不确定你想做什么。我认为您想在处理后删除 flac 文件。您有几种选择:您可以先转换所有 ffmpeg 文件,然后将它们全部删除;或者您可以在处理完每个文件后将其删除。我建议后者,否则如果转换成功的话,很难只删除flac文件。

    这里使用find … -exec 比使用xargs 更简单。对于每个flac文件,调用ffmpeg,如果ffmpeg成功则删除文件。如果您的查找没有 -delete 操作,请改用 -exec rm {} \;。使用中间 shell 来构造输出文件名。

    find . -type f -name '*.flac' \
         -exec sh -c 'ffmpeg -i "$0" -acodec libmp3lame -ab 320k "${0%.*}.mp3"' {} \; \
         -delete
    

    您可以在 shell sn-p 中使用rm 命令。

    find . -type f -name '*.flac' \
         -exec sh -c 'ffmpeg -i "$0" -acodec libmp3lame -ab 320k "${0%.*}.mp3" && rm "$0"' {} \;
    

    对于某些版本的find,如果您希望输出文件被称为foo.flac.mp3,您可以跳过中间shell。

    find . -type f -name '*.flac' \
         -exec ffmpeg -i {} -acodec libmp3lame -ab 320k {}.mp3 \; \
         -delete
    

    【讨论】:

    • 第二个选项看起来是最好和最简单的选项,完全按照问题的要求做,不使用管道。非常优雅的解决方案。
    【解决方案3】:

    命令rm 不接受标准输入的输入,因此您需要使用xargs 发送输入,就像您为ffmpeg 所做的那样

    试试这个:

    find . -type f -name '*.flac' -print0 |
        xargs -0i bash -c 'ffmpeg -i {} -acodec libmp3lame -ab 320k \"{}.mp3" ; rm -rf {}'
    

    这会将rm 添加到xargs 执行的命令中,本质上是使用bash -c 创建一个内联shell 脚本。

    【讨论】:

      【解决方案4】:

      首先,“它不让我”不是描述问题的最佳方式。您应该发布错误消息或描述发生的情况。

      其次,我不太明白您想要实现的目标,但您没有将rmxargs 一起使用,您只需将某些内容通过管道传输到rmrm 不是这样工作的。

      find . -type f -name '*.flac' -print0 | xargs -0i rm "{}"
      

      例如,可能会起作用。我没有在这里使用rm -r,因为find 无论如何只会查找文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-14
        • 2011-11-20
        • 2011-10-20
        • 2016-03-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多