Bash 使用原始文件作为目标文件

Bash Use Origin File as Destination File

我正在使用 ImageMagick bash 工具,它使用以下形式的命令:

<command> <input filename> <stuff> <output filename>

我正在尝试执行以下命令:

<command> x.png <stuff> x.png

但对于目录中的每个文件。我试过了:

<command> *.png <stuff> *.png

但这没有用。对目录中的每个文件执行这样的命令的正确方法是什么?

对于单个文件,这样做:

<command> x.png <stuff> temp.png && mv temp.png x.png

对于一组文件,这样做:

#!/bin/bash
find `pwd` -name \*.png | while read line
do
<command> "$line" <stuff> temp.png && mv temp.png "$line"
done

将包含 png 文件的文件夹中的脚本另存为 processpng。将其设为可执行文件并 运行 它。

./processpng

上面脚本的一般版本,它将包含上述文件的文件夹的路径作为参数如下:

#!/bin/bash
find  -name \*.png | while read line
do
<command> "$line" <stuff> temp.png && mv temp.png "$line"
done

将脚本另存为 processpng 在计算机的任何位置。使它成为一个可执行文件并且 运行 它像 :

./processpng /path/to/your/png/folder

编辑:

结合@anishsane 的解决方案,实现相同目标的紧凑方式 结果将是

#!/bin/bash
find  -name \*.png -exec bash -c "<command> {} <stuff> temp.png && mv temp.png {}"

find .... -exec 的上下文中:

{} indicates (contains) the result(s) from the find expression. Note that empty curly braces {} have no special meaning to shell so we can get away without escaping {}

注:强调我的。

参考:这个AskUbuntu Question.

许多 Unix command-line 工具,例如 awksedgrep 是 stream-based 或 line-oriented,这意味着它们处理一次一行归档。使用这些时,有必要将输出写入中间文件,然后将其重命名(使用 mv)返回原始输入文件。这样做的原因是您可能在全部读取输入文件之前对其进行了改写,因此您将破坏您的输入。在那种情况下,@sjsam 的回答是绝对正确的 - 特别是因为他小心地在两者之间使用 && 以便在命令不成功时 mv 不会完成。

然而,在 ImageMagick 及其 convertcomparecompose 命令的特定情况下,NOT 是这种情况。这些程序是 file-oriented,而不是 line-oriented,因此它们在写入任何输出之前将 整个输入文件 读入内存。原因是他们在开始处理之前经常需要知道图像中是否有任何透明像素,或者图像中有多少种颜色,而在读取整个文件之前他们无法知道。因此,它是绝对安全的,事实上 惯用的 使用相同的输入文件名作为输出文件名,如下所示:

convert image.jpg ... -crop 100x100 -colors 16 ... image.jpg

在回答您的问题时,当您有多个文件要处理时,首选方法是使用专门用于处理多个文件的 mogrify 工具(也是 ImageMagick 套件的一部分)。所以,你会这样做:

mogrify -crop 100x100 -colors 16 *.jpg

这将用结果覆盖您的输入文件 - 这正是您所要求的。如果您不希望它覆盖您的输入文件,您可以添加一个 -path 告诉 ImageMagick 输出目录的路径,如下所示:

mogrify -path /path/to/thumbnails -thumbnail -colors 16 *.jpg

如果 Windows COMMAND.EXE/CMD.EXE 有太多文件无法扩展并传递给 mogrify,您可以让 ImageMagick 在内部扩展 glob(星号)像这样并能够处理无限数量的文件:

mogrify -crop 100x100 '*.jpg'

重点是 mogrify 语法不仅简洁,而且可跨 Windows/OSX/Linux 移植,还意味着您只需要创建 单个进程 来处理你所有的图像,而不是必须编写一个 FOR 循环并为可能的数千个文件中的每一个创建和执行一个 convert 进程和一个 mv 进程 - 所以它效率更高,更少 error-prone.