我有以下 JPEG 文件:
$ ls -l
-rw-r--r-- 1 user group 384065 janv. 21 12:10 CamScanner 01-10-2022 14.54.jpg
-rw-r--r-- 1 user group 200892 janv. 10 14:55 CamScanner 01-10-2022 14.55.jpg
-rw-r--r-- 1 user group 283821 janv. 21 12:10 CamScanner 01-10-2022 14.56.jpg
我$ img2pdf
用来将每个图像转换为 PDF 文件。要做到这一点 :
$ find . -type f -name "*.jpg" -exec img2pdf "{}" --output $(basename {} .jpg).pdf \;
结果 :
$ ls -l *.pdf
-rw-r--r-- 1 user group 385060 janv. 21 13:06 CamScanner 01-10-2022 14.54.jpg.pdf
-rw-r--r-- 1 user group 201887 janv. 21 13:06 CamScanner 01-10-2022 14.55.jpg.pdf
-rw-r--r-- 1 user group 284816 janv. 21 13:06 CamScanner 01-10-2022 14.56.jpg.pdf
如何删除.jpg
PDF 文件名的一部分?即,我想要CamScanner 01-10-2022 14.54.pdf
而不是CamScanner 01-10-2022 14.54.jpg.pdf
。
单独使用,$ basename filename .extension
打印不带扩展名的文件名,例如:
$ basename CamScanner\ 01-10-2022\ 14.54.jpg .jpg
CamScanner 01-10-2022 14.54
$ find
但似乎语法在我的命令中不起作用。知道为什么吗?
注意:如果你替换$ img2pdf
它$ echo
是一样的,$ basename
不要去掉.jpg
部分:
$ find . -type f -name "*.jpg" -exec echo $(basename {} .jpg).pdf \;
./CamScanner 01-10-2022 14.56.jpg.pdf
./CamScanner 01-10-2022 14.55.jpg.pdf
./CamScanner 01-10-2022 14.54.jpg.pdf
您的命令的问题在于,shell甚至在它开始运行之前
find
就执行了命令替换(作为评估参数应该是什么的一个步骤)。basename
find
find
每当您需要为通过 找到的路径名运行带有可选参数的简单实用程序以外的任何东西时
find
,例如,如果您需要执行任何管道、重定向或扩展(如您的问题中所示),您将需要使用 shell 来执行这些操作事物:或者,更有效(每次调用
sh -c
都会处理一批找到的路径名),或者,与
zsh
,这使用 globbing 限定符
.DN
仅匹配常规文件 (.
),允许匹配隐藏名称 (D
),并在未找到匹配项时删除模式 (N
)。然后,它使用:t
修饰符提取 的“尾部”(文件名组件)$pathname
,:r
提取生成的基本名称的“根”(无文件名后缀),然后添加.png
到末尾。请注意,上述所有变体都会将输出写入当前目录,而不管 JPEG 文件是在哪里找到的。如果您所有的 JPEG 文件都在当前目录中,则绝对不需要使用
find
,并且您可以使用一个简单的循环来扩展*.jpg
globbing 模式:参数替换从 的值的末尾
${pathname%.jpg}
删除。如果您想将输出写入找到 JPEG 文件的原始目录,您可能希望使用此替换来代替,以防您在多个目录中使用,例如,类似.jpg
$pathname
basename
find
也可以看看:
从务实的角度来看,一旦您达到了您在问题末尾所描述的状态:
您可以选择使用
rename
来获取所需的最终文件名:@Ulrich Schwarz 的评论很贴切。为了使它完整,让我们假设您没有任何带有引号或单引号的文件名。
调整您的
find
语法以简单地输出基本名称而没有 .jpg,然后在适当的情况下使用和扩展awk
来重构img2pdf
语法:.jpg
.pdf
此
find
命令将输出裸基本名称:现在将这些基本名称传递给
awk
并让 awk 构造正确的语法img2pdf
:如果该语法看起来不错,则将其通过管道传输到您最喜欢的 shell。