basename命令无法按预期工作

Reg*_*ser 4 unix bash shell rename ubuntu-12.04

我编写了一个shell脚本,将我的大量JPG转换为pdf

 #!/bin/bash
set -xv
for i in `ls -v *.JPG`;
 do i=$(basename "$i")
 convert "$i" "$i.pdf" ;
 done
Run Code Online (Sandbox Code Playgroud)

JPG是

DSCN2612.JPG DSCN2618.JPG DSCN2624.JPG

我得到的转换后的pdf有名字

DSCN2612.JPG.pdf DSCN2618.JPG.pdf DSCN2624.JPG.pdf

现在注意在我的shell脚本中使用basename命令我希望得到pdf的结果名称

DSCN2612.pdf DSCN2618.pdf DSCN2624.pdf

输出在哪里不同.我正在使用Ubuntu 12.04和basename --version显示

basename(GNU coreutils)8.13版权所有(C)2011 Free Software Foundation,Inc.许可证GPLv3 +:GNU GPL版本3或更高版本 http://gnu.org/licenses/gpl.html.这是免费软件:您可以自由更改并重新分发它.在法律允许的范围内,不提供任何担保.

当我在一个终端上输入时

basename DSCN2612.JPG
我得到了输出

DSCN2612.JPG

我期待的地方

DSCN2612

只有这样我的理解错误或者我使用这个脚本的方式有一些错误.

jed*_*rds 7

basename命令有两个用途,剥离路径前缀和(可选)剥离后缀.

例如,要删除路径前缀,只需将其传递给路径即可

basename /path/to/file.ext
# file.ext
Run Code Online (Sandbox Code Playgroud)

额外剥离后缀,你需要告诉basename您要剥去后缀,例如

basename /path/to/file.ext .ext
# file

basename DSCN2612.JPG .JPG
# DSCN2612
Run Code Online (Sandbox Code Playgroud)

因此,basename不会"自动检测"后缀,因为在unix中,文件不一定有后缀.换句话说,句点之后的字母不一定是后缀,因此您需要明确告诉它要删除哪个后缀.

但是,有一些bash特定的替代"自动检测"和剥离.例如,

x="file.ext"
echo ${x%.*}
# file
Run Code Online (Sandbox Code Playgroud)

如果不了解更多,我可能会将您的脚本编写为

for jpg in *.JPG; do
    base=${jpg%.*}
    convert "$jpg" "$base.pdf"
done
Run Code Online (Sandbox Code Playgroud)