找到arcana:无法让管道在-exec行中工作

找到arcana:无法让管道在-exec行中工作

如何通过 sed 将查找结果传输到 xform 流,然后使用转换后的流作为脚本的两个参数之一? IE:

寻找出现 file1.tiff (以及其他文件)
sed转换 file1.tiff --> file1.jpg
使用这两个参数执行命令:转换 file1.tiff file1.jpg

我已经尝试了很多方法,但无法得到它。这是一种带来风味的尝试:

find ./out -regex ".*_p[bg]_.*tiff" -exec echo "Processing {}" \; -exec convert {} `echo {} | sed s/tiff/jpg/` \;

我应该放弃并编写一个 Python 脚本来分别完成这些部分,但我最终尝试学习 UNIX 工具,现在我很着迷。帮助!

答案1

我不确定里面是否可以有管道-execfind -exec echo {} \| sed s/tiff/jpg \;似乎不起作用。

如果认为你最好的选择是制作一个脚本来进行转换,例如

转换_tiff_to_jpg:

#!/bin/bash
echo "Processing $1"
convert "$1" "${1/%tiff/jpg}"

find -exec并按照您的预期调用它:

find ./out -regex ".*_p[bg]_.*tiff" -exec convert_tiff_to_jpg {} \;

有几种方法可以使用 来做到这一点find -print0 | xargs -0,但它们都非常丑陋:

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "$(echo "$filename" | sed 's/tiff$/jpg/')"
done

或者

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "${filename/%tiff/jpg}"
done

或者

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
    xargs -0 -I FILE bash -c 'F="FILE"; echo "$F" "${F/%tiff/jpg}"'

请注意,我更改s/tiff/jpg为,s/tiff$/jpg以便如果tiff出现在文件名末尾以外的任何位置,则不会更改。

答案2

您试图将 shell 命令传递给-exec,但它需要的是程序的名称和参数列表。所以你需要明确地告诉它启动一个 shell。

find ./out -regex ".*_p[bg]_.*tiff" \
     -exec sh -c 'echo "Processing $0"; convert "$0" "${0%.tiff}.jpg"' {} \;
  • sh -c 'shell code, not using single quotes'当您在需要带参数的命令的上下文中需要 shell 功能时,这是一个相对常见的习惯用法。
  • -exec sh -c 'do stuff with "$0"' {} \;是一个find与 shell 相关的惯用语。某些版本的 find 允许{}直接在 shell 代码中写入,但这是一个坏主意,不仅因为某些 find 版本不允许,而且还因为如果文件名包含特殊字符(例如引号),这可能会严重破坏。因此,文件名作为其第 0 个参数传递给 shell,并且脚本使用 shell 变量$0来引用该文件。
  • echo tiff_filename | sed s/tiff/jpg/是一种复杂、低效、不正确且脆弱的更改文件名的方法。它复杂且低效,因为您正在调用 sed。这是错误的,因为您要替换tiff文件中的任何位置:例如tiffany.tiff将变成jpgany.tiff.它很脆弱,因为它不适用于某些文件名(echomangle 反斜杠的某些实现)。相反,请使用${0%.tiff}删除.tiff文件名中的后缀$0

相关内容