将“.tif”图像批量转换为“.jpg”

将“.tif”图像批量转换为“.jpg”

我正在使用 Manjaro GNU/Linux。我有一个名为files;的目录在这个目录下,我有大约 650 个子目录,名称如file1file2file3等。

每个子目录下有 2 到 11 个.tif图像。

我想编写一个命令或脚本来自动将所有.tif图像转换为.jpeg.jpg使它们保留在相同的子目录中并具有与以前相同的名称。

我知道有这样的命令:

convert source.tif ~/converted.jpg

你能帮忙吗?

谢谢!

答案1

最简单的方法是find执行一个简短的内联脚本,该脚本使用.tif文件名后缀转换每个找到的文件:

find files/ -name '*.tif' -type f -exec sh -c '
    for pathname do
        convert "$pathname" "${pathname%.tif}.jpg"
    done' sh {} +

上面的内联脚本将通过批量找到的常规文件的路径名(其后缀在目录下找到)sh -c来调用。参数替换会从 的值中删除后缀并附加到末尾。find.tiffiles${pathname%.tif}.jpg.tif$pathname.jpg

用作files/file*/搜索路径,而不是仅在以 string 开头files/的这约 650 个子目录中查找,而忽略任何其他子目录。filesfile

这会将文件保留在原位,但如果您在循环中的命令后面.tif添加,则可以在成功转换后删除它们。&& rm "$pathname"convert


zshshell 中,您可以放弃find并依赖 shell 更高级的文件名匹配和字符串操作功能:

for pathname in files/**/*.tif(D-.); do
    convert $pathname $pathname:r.jpg
done

此处,将展开为名称以目录中或目录下任意位置files/**/*.tif(D-.)结尾的所有常规文件的列表。通配符末尾的 使得通配符模式仅匹配常规文件(可能具有“隐藏”名称)。.tiffiles(D-.)

之后给出路径名的“根”(不带文件扩展名:r$pathname名称)。

用于files/file*/**/*.tif(D-.)将搜索限制为仅file*搜索子目录中的文件。


使用bashshell,您可以执行与上面类似的操作,如下所示:

shopt -s dotglob failglob globstar
for pathname in files/**/*.tif; do
    convert "$pathname" "${pathname%.tif}.jpg"
done

此处设置的 shell 选项启用隐藏名称的通配和通配运算符的使用**。它还会使不匹配的模式生成错误,就像zshshell 中的默认情况一样。

答案2

对于 7,000 多个文件,您将需要花很长时间按顺序执行它们,因此我建议利用当今的多核 CPU 并使用GNU 并行让它们并行转换。它不仅速度更快,还可以非常简单地为您操作后缀,并为您提供进度报告并进行空运行,看看它会做什么,而无需实际执行任何操作。

看起来bash像这样:

shopt -s failglob globstar
parallel --dry-run magick {} {.}.jpg ::: files/**/*.tif

输出

magick files/file1/1.tif files/file1/1.jpg
magick files/file2/1.tif files/file2/1.jpg
magick files/file1/2.tif files/file1/2.jpg
magick files/file2/2.tif files/file2/2.jpg
magick files/file3/1.tif files/file3/1.jpg
magick files/file3/2.tif files/file3/2.jpg

如果看起来正确,请删除--dry-run并再次进行真正的操作。


如果您有太多文件并出现错误,您可以将文件名通过管道传输到magickfrom find,这里我还添加了--bar进度条:

find files -iname "*.tif" -print0 | parallel -0 --dry-run --bar magick {} {.}.jpg

请注意,与某些答案不同,如果您的 TIFF 文件具有大写后缀,这也将起作用。

答案3

cd进入包含子文件夹的主目录后。

IFS=$'\n'
for i in $(find -type f -name "*tiff"); do 
    echo $i
    convert $i $i.jpg
done

find -type f -name "*tiff" -exec rm {} \;


IFS 是内部字段分隔符

我看到的一个问题是我无法提取basename文件的内容

在移动到大文件夹之前,不要忘记先在小文件夹中尝试

答案4

我会使用类似于此的脚本:

#!/bin/bash
if [[ $# -gt 0 ]]
then
  if [[ -d $1 ]]
  then
    cd $1
  else
    echo "Given path leads to a file or the directory you are loking does not exist!"
    exit 1
  fi
fi
for dir in */
do
  echo "Changing directory to $dir"
  cd $dir
  for image in *
  do
    if [[ -f "$image" ]]
    then
      filename="${image%.*}"
      extension="${image##*.}"
      if [[ "$extension" =~ ^ti[f]{1,2}$ ]]; then
        echo "Converting $image to ${filename}.jpg"
        convert "$image" -compress JPEG -quality 50 "${filename}.jpg"
      fi
    fi
  done
  cd - > /dev/null
done

设置你的脚本:

  1. 将其另存为batchJPEGConvert.sh
  2. 使用chmod 755 batchJPEGConvert.sh命令使该文件可执行
  3. 使用sudo cp batchJPEGConvert.sh /usr/local/bin命令使该脚本可以在您的系统中访问

batchJPEGConvert.sh您可以通过键入或 来运行此脚本batchJPEGConvert.sh path。第一个选项将在当前工作目录中运行此脚本。另一个选项将尝试将工作目录更改为给定的小路并在那里运行脚本。该脚本将仅有的转换以 .tiff 或 .tif 扩展名结尾的文件。它还将应用 JPEG 压缩。

请注意,此脚本仅适用于结构类似于此的目录:

test
├── 1
│   ├── polski.jpg
│   └── polski.tiff
└── 2
    ├── polski.jpg
    └── polski.tif

相关内容