使用命令 (ls) 的输出并在另一个命令中使用它的脚本

使用命令 (ls) 的输出并在另一个命令中使用它的脚本

我有一组 pdf 文件,想转换为 epub。我知道 Calibre 的命令ebook-convert可以解决问题(我可以补充一下)。但是我有不止一个文件。

我希望能够运行一个脚本,ls > file然后运行某个文件并解析它,以便每个条目都是一个变量。然后使用变量 to 作为ebook-convert;的输入文件并以某种方式将变量作为输出文件,但将 a 附加.epub到文件名的末尾?

答案1

我将扩展杰森·瑞恩的答案,解释了是什么,但没有解释如何或为什么。

您可以使用一个命令的输出作为另一个命令的参数。这就是所谓的命令替换

some_text='Hello, world'
uppercased="$(echo "$some_text" | tr a-z A-Z)"
echo "Now, it's $uppercased"

然而,$(ls …)这很可怕,有两个原因:

  • 不解析 ls 的输出。它不是被设计为可解析的。
  • "$(some-command)"给你一个字符串,它是该命令的输出。如果您有一个返回元素列表的命令,则需要将该字符串解析为单个元素。除非你能找到一个简单的分隔符,否则这是繁琐且不可靠的。对于文件名,您无法轻松找到分隔符,因为大多数 unice 上的文件名可以包含每个字符⁰。

请注意,如果您编写$(some-command)而不是"$(some-command)",则命令的输出将被拆分为单词并进行通配。在您理解前一句之前,请始终在命令替换两边加上双引号。当您确实理解时,请始终添加双引号,除非您知道为什么不能添加双引号。

幸运的是,生成与特定模式匹配的文件列表是 shell 中内置的一项功能。它被称为通配

echo *.pdf

要对多个文件执行操作,可以使用循环。

for x in *.pdf; do …; done

剩下的障碍是生成目标文件的名称。 shell 有一些简单的文本操作命令,其中包括${foo%SUFFIX}获取删除后缀的变量的值。 (还有${foo#PREFIX}。)

for x in *.pdf; do
  ebook-convert "$x" "${x%.pdf}.epub"
done

请注意变量替换周围的双引号。原因与命令替换相同。

除了空字符,但大多数 shell 无法处理这些。

答案2

这可能是一个更简单的方法:

for file in *.pdf; do
    ebook-convert "$file" "${file%.pdf}.epub"
done
exit 0

答案3

一句话回答,具有转换运行的轻微优势平行线:

parallel ebook-convert {} {.}.epub ::: *.pdf

我已经习惯不使用for 循环不再在壳里了。它们都可以整齐地替换为GNU 并行

相关内容