如何使用管道指定输出文件名?

如何使用管道指定输出文件名?

我使用 find 返回目录及其子目录中的文件列表:

find $directory -type f -name "*.epub"

然后我想使用一个需要指定输入和输出文件名的命令:

ebook-convert input.epub output.txt

我想将每个转换.epub.txt使得输出存储在与输入相同的目录/子目录中。简单的管道不起作用。

find $directory -type f -name "*.epub" | ebook-convert

我该怎么做呢?

答案1

诀窍是不是创建一个文件列表,然后对其进行迭代(参见例如为什么循环查找的输出是不好的做法?)。

find "$directory" -type f -name '*.epub' -exec ebook-convert {} output.txt \;

*.epub这将查找目录中或目录下名称匹配的所有常规文件$directory。对于每个命令,ebook-convert都会使用找到的文件的路径名作为其第一个参数和output.txt第二个参数来执行。

这显然会覆盖output.txt每个找到的文件,但以下方法可以通过创建一个与原始文件同名的文件并-converted.txt添加到名称末尾(与原始文件在同一目录中)来解决这个问题:

find "$directory" -type f -name '*.epub' -exec ebook-convert {} {}-converted.txt \;

可能不适用于 的所有实现,find因为它可能不会用找到的文件的路径名替换第二个{}(因为它与另一个字符串连接;但例如 GNUfind处理它)。要解决这个问题:

find "$directory" -type f -name '*.epub' -exec sh -c '
    for pathname do
        ebook-convert "$pathname" "$pathname"-converted.txt
    done' sh {} +

使用支持通配模式的shell,例如bash或:zsh**

for pathname in "$directory"/**/*.epub; do
    ebook-convert "$pathname" "$pathname"-converted.txt
done

(这需要shopt -s globstar并将bash处理任何匹配名称,不仅仅是常规文件,除非您使用*.epub(.)inzsh或显式-f测试 in bash)

相关内容