从 linux find 访问父目录和祖目录并传递给 xargs

从 linux find 访问父目录和祖目录并传递给 xargs

我正在尝试对目录中的所有 tiff 进行批量 imagemagick 转换。

目录结构如下:

test    
    123
       456
          image.tif

    256
       857
          anotherimage.tif

我尝试使用 find 来查找所有图像,然后将它们传递到 xargs 中,以便 imagemagick 将其转换为 jp2。输出文件名将是父目录和父目录名称的组合,因此在上面的示例中,image.tif将转换为123456.jp2

我的find工作正常,但就是无法获得正确的 imagemagick 和 find 参数组合来实现我需要的功能。这是使用 xargs 的 find。{grandparentdir} 和 {parentdir} 是我缺少的部分的占位符!

find /var/tmp/test -type f \( -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" \) -mtime -1 | xargs convert -quality 100 \var\tmp\test\{granparentdir}{parentdir}.jp2"

答案1

运行 shellfind -exec并操作那里的路径:

find /var/tmp/test -type f \
   \( -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" \) \
   -mtime -1 \
   -exec sh -c '
      for f do
         parent="$(basename "$(dirname "$f")")"
         grandparent="$(basename "$(dirname "$(dirname "$f")")")"
         printf "%s\n" "$grandparent$parent.jp2"
         # convert   -- whatever arguments you want
      done
   ' sh-find {} +

我使用dirnamebasename的方式并不理想。如果需要,您可以改用 shell 参数扩展(${f%/*}等)和例如。realpath

重点是你运行一个 shell,你可以在其中做任何事情

在我的示例中,整个 shell 代码都是单引号的(这是因为外壳程序的任何扩展都可能是不安全的,内壳程序将解析结果)。如果您需要在代码中使用单引号,那么正确的引用将变得有些复杂。在这种情况下,不要-exec sh -c '…' sh-find {} +考虑包含代码的文件-exec sh ./script {} +在哪里script。在文件内部,您可以像在任何其他 shell 脚本中一样引用。

如果需要 Bash,请使用-exec bash。使用您需要的任何 shell。或者其他。如果需要 Python,请使用-exec python。这种方法非常强大。


更多信息:

答案2

这可能对其他人有帮助。我最终将命令分成两个:

  1. 首先转换文件
  2. 之后移动/重命名

1. 使用 mogrify 进行变换

find /var/tmp/test -type f -not -name "*.thumb*" -not -name "*.500x500*" \( -name "*.jpg" -o -name "*.JPG" -o -name "*.png" -o -name "*.PNG" -o -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" -o -name "*.bmp" -o -name "*.BMP" \) | xargs mogrify -format jp2

2.重命名并将文件移动到我选择的位置

find /var/tmp/test -type f -name "*.jp2" -execdir bash -c \ 'old="{}"; new="$(cd ..; basename -- "$PWD")$(basename -- "$PWD").jp2"; mv "$old" /var/tmp/test/"$new"' - {} \;

相关内容