bash basename 命令未按预期工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15612255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:58:59  来源:igfitidea点击:

basename command not working as expected

bashshellunixubuntu-12.04rename

提问by Registered User

I wrote a shell script to convert a lot of JPGs at my end to pdf

我写了一个shell脚本把我最后的很多JPG转换成pdf

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

the JPGs are

JPG 是

DSCN2612.JPG DSCN2618.JPG DSCN2624.JPG

DSCN2612.JPG DSCN2618.JPG DSCN2624.JPG

and the converted pdfs I get are having names

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

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

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

Now note the use of basename command in my shell script I expect the resulting name of pdf to be

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

DSCN2612.pdf DSCN2618.pdf DSCN2624.pdf

DSCN2612.pdf DSCN2618.pdf DSCN2624.pdf

Where is the output is different. I am using Ubuntu 12.04 and basename --version shows

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

basename (GNU coreutils) 8.13 Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

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

when on a terminal I just type

在终端上时,我只需输入

basename DSCN2612.JPG
I get the output

DSCN2612.JPG

basename DSCN2612.JPG
我得到输出

DSCN2612.JPG

where as I expect

正如我所期望的那样

DSCN2612

DSCN2612

only so is my understanding wrong or there is some error the way I am using this script.

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

回答by jedwards

The basenamecommand has two uses, stripping path prefixes and (optionally) stripping suffixes.

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

To strip a path prefix, you can simply pass it a path, for example

要去除路径前缀,您可以简单地将路径传递给它,例如

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

To additionally strip a suffix, you need to tell basenamethe suffix you wish to strip, for example

要额外去除后缀,您需要告诉您要去除basename的后缀,例如

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

basename DSCN2612.JPG .JPG
# DSCN2612

So, basenamewon't "auto-detect" a suffix because in unix, files don't necessarily have suffixes. In other words, letters after a period aren't necessarily suffixes, so you need to explicitly tell it what suffix to strip.

因此,basename不会“自动检测”后缀,因为在 unix 中,文件不一定有后缀。换句话说,句号后面的字母不一定是后缀,所以你需要明确告诉它要去掉什么后缀。

There are some bash-specific alternatives to "auto-detect" and strip, however. For example,

然而,有一些 bash 特定的替代方案可以替代“自动检测”和剥离。例如,

x="file.ext"
echo ${x%.*}
# file

Without knowing more, I might write your script as

在不知道更多的情况下,我可能会将您的脚本编写为

for jpg in *.JPG; do
    base=${jpg%.*}
    convert "$jpg" "$base.pdf"
done