【问题标题】:How does `extension="${filename##*.}"` work in bash? [duplicate]`extension="${filename##*.}"` 在 bash 中如何工作? [复制]
【发布时间】:2016-06-10 12:18:25
【问题描述】:

在网上查看如何获取文件的扩展名和名称时,我发现:

filename=$(basename "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}

${} 语法是什么...?我知道正则表达式,但 "${filename##*.}""${filename%.*} 无法理解。

还有,有什么区别:

filename=$(basename "$fullfile")

filename=`basename "$fullfile"`

...? 在 Google 中查找是一场噩梦,因为这些奇怪的字符...

【问题讨论】:

  • 我的 Google 工作:Shell Parameter Expansion
  • @e0k:该链接很有帮助,但 OP 的观点是,如果您不知道某个功能的 名称,则很难仅通过它所涉及的符号来搜索它.
  • 在手册页中搜索 ## 会直接转到相关文档。

标签: bash


【解决方案1】:

${filename##*.} 表达式是参数扩展(“参数”是其他语言称为“变量”的 shell 功能的技术名称)。普通的${varname} 是名为varname 的参数的值,如果这就是你所做的一切,你可以去掉花括号,只输入$varname。但是如果你把花括号留在那里,你可以在名字后面放其他东西来修改结果。 #% 是一些最基本的修饰符 - 它们删除匹配通配符模式的字符串的前缀或后缀。 # 从开头删除,% 从末尾删除;在每种情况下,符号的单个实例删除最短的匹配字符串,而双符号匹配最长的。所以${filename##*.} 是“文件名的值,从开头到最后一个句点都被删除了”,而${filename%.*} 是“文件名的值,从最后一个句点到最后一个句点都被删除了”。

反引号语法 (`...`) 是在 Bourne shell 中进行命令替换的原始方式,此后已被 Perl 和 Ruby 等语言借用以合并对系统命令的调用。但它不能很好地处理嵌套,它甚至允许嵌套的尝试意味着引用在它们内部的工作方式不同,这一切都非常令人困惑。较新的 $(...) 语法,最初是在 Korn shell 中引入,然后被 Bash 和 zsh 采用并由 POSIX 编码,让引用在嵌套替换的所有级别上工作相同,并与 ${...} 参数扩展很好地对称.

【讨论】:

  • 谢谢马克。我使用 Bash 的方式与我过去使用 Bourne Shell 的方式相同,当时我是在 AIX 中学习 Bash 的。我想是时候让我再好好看看它了!
【解决方案2】:

正如@e0k 在对该问题的评论中所说,${varname...} 语法是 Bash 的 parameter (variable) expansion。它有自己的语法,与正则表达式无关;它包含一系列广泛的功能,包括:

  • 指定默认值
  • 前缀和后缀剥离
  • 字符串替换
  • 子串提取

`...`$(...)(都是所谓command substitutions的形式)的区别是:

  • `...` 是较旧的语法(通常称为已弃用,但严格来说并非如此)。
  • $(...) 是它的现代等价物,它便于嵌套使用,并且在引用时更直观。
  • 请参阅here 了解更多信息。

【讨论】:

    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多