如何使用字符串作为文件名输入来执行 imagemagick - bash
How to execute imagemagick with a string as input for filenames - in bash
我正在尝试编写代码来执行以下操作。
1:将输入行中的所有目录名称转换为字符串(目录输入的数量可能会有所不同)
2:对于这些目录中的所有 tiff 文件,使用相同名称蒙太奇图像(使用 imagemagick)并将其保存在主文件夹或给定文件夹中。
我想合并两个或多个图像(取决于命令行输入的目录数量)。每个目录都有与另一个目录同名的图像输出。我想合并给定目录中具有相同名称的文件
下面是我写的代码,但它没有将 $name 作为变量传递给 montage 命令。
我在这里做错了什么?任何帮助将不胜感激。
for arg in "$@"; do #
n1=$arg
fname+=$n1"${name} " #Get all the directory names in a string with $name at the end. for eg: Baseline/$name
done
echo $fname
for n in $arg/*.tif; do
name="$(basename "$n")"
name1=$(echo "$name" | cut -f 1 -d '.')
montage -tile 3x3 $fname name1.png
exit
done
更多详情
更新答案
感谢您的澄清,如果您将以下内容另存为 monty.sh
并使其可执行:
,您就可以做您想做的事了
chmod +x monty.sh
代码如下:
#!/bin/bash
# Goto first subdirectory and take it off args list
cd ""
shift
# Grab remaining directory names into array
friends=( "$@" )
> echo "DEBUG: friends=${friends[@]}"
# Iterate over files in first directory
for this in *.tiff ; do
>&2 echo "DEBUG: this=$this"
# Generate list of files to montage
{
# ... starting with this one...
echo "$this"
# ... and adding in his friends
for friend in "${friends[@]}" ; do
next="../${friend}/${this}"
>&2 echo "DEBUG: next=$next"
if [ -f "$next" ] ; then
echo "$next"
else
>&2 echo "ERROR: file $next is missing"
fi
done
} | magick montage -tile 3x @- ../"${this/tiff/png}"
done
那么你的命令将是:
./monty.sh Output1 Output2 Output3
或者更简洁地说:
./monty.sh Output{1,2,3}
如果您不熟悉 bash
语法,for
循环中间的代码本质上是在做:
...
...
{
echo first filename to montage onto stdout
echo second filename to montage onto stdout
echo third filename to montage onto stdout
} | magick montage <ALL FILENAMES ON STDIN> result.png
因此,将 {...}
中的所有错误消息发送到 stderr
非常重要,否则错误消息将发送到 montage
命令,该命令会将它们解释为文件名。这就是为什么所有调试语句都以 >&2 echo ...
开头的原因,因为这会将它们定向到 stderr
,因此它们不会与 stdout
.
混淆
原答案
我不明白你想做什么,但如果你能把所有的文件名都写进ImageMagick的stdin
,你就可以制作蒙太奇他们是这样的:
find . -name "*.tif" -print | magick montage -geometry +0+0 -tile x3 @- result.png
我正在尝试编写代码来执行以下操作。
1:将输入行中的所有目录名称转换为字符串(目录输入的数量可能会有所不同)
2:对于这些目录中的所有 tiff 文件,使用相同名称蒙太奇图像(使用 imagemagick)并将其保存在主文件夹或给定文件夹中。
我想合并两个或多个图像(取决于命令行输入的目录数量)。每个目录都有与另一个目录同名的图像输出。我想合并给定目录中具有相同名称的文件
下面是我写的代码,但它没有将 $name 作为变量传递给 montage 命令。 我在这里做错了什么?任何帮助将不胜感激。
for arg in "$@"; do #
n1=$arg
fname+=$n1"${name} " #Get all the directory names in a string with $name at the end. for eg: Baseline/$name
done
echo $fname
for n in $arg/*.tif; do
name="$(basename "$n")"
name1=$(echo "$name" | cut -f 1 -d '.')
montage -tile 3x3 $fname name1.png
exit
done
更多详情
更新答案
感谢您的澄清,如果您将以下内容另存为 monty.sh
并使其可执行:
chmod +x monty.sh
代码如下:
#!/bin/bash
# Goto first subdirectory and take it off args list
cd ""
shift
# Grab remaining directory names into array
friends=( "$@" )
> echo "DEBUG: friends=${friends[@]}"
# Iterate over files in first directory
for this in *.tiff ; do
>&2 echo "DEBUG: this=$this"
# Generate list of files to montage
{
# ... starting with this one...
echo "$this"
# ... and adding in his friends
for friend in "${friends[@]}" ; do
next="../${friend}/${this}"
>&2 echo "DEBUG: next=$next"
if [ -f "$next" ] ; then
echo "$next"
else
>&2 echo "ERROR: file $next is missing"
fi
done
} | magick montage -tile 3x @- ../"${this/tiff/png}"
done
那么你的命令将是:
./monty.sh Output1 Output2 Output3
或者更简洁地说:
./monty.sh Output{1,2,3}
如果您不熟悉 bash
语法,for
循环中间的代码本质上是在做:
...
...
{
echo first filename to montage onto stdout
echo second filename to montage onto stdout
echo third filename to montage onto stdout
} | magick montage <ALL FILENAMES ON STDIN> result.png
因此,将 {...}
中的所有错误消息发送到 stderr
非常重要,否则错误消息将发送到 montage
命令,该命令会将它们解释为文件名。这就是为什么所有调试语句都以 >&2 echo ...
开头的原因,因为这会将它们定向到 stderr
,因此它们不会与 stdout
.
原答案
我不明白你想做什么,但如果你能把所有的文件名都写进ImageMagick的stdin
,你就可以制作蒙太奇他们是这样的:
find . -name "*.tif" -print | magick montage -geometry +0+0 -tile x3 @- result.png