如何在 Bash 中分隔文件名和扩展名

如何在 Bash 中分隔文件名和扩展名
如何在 Bash 中分隔文件名和扩展名

介绍:

Bash 中处理文件时,您可能经常需要将文件名与其扩展名分开。常见的方法是使用“cut”命令,但此方法可能会因文件名包含多个句点而失败。

例如,像“a.b.js”这样的文件名会被错误地拆分为“a”和“b.js”,而不是“a.b”和“js”。尽管 Python 通过 os.path.splitext() 提供了一个简单的解决方案,但使用 Python 可能并不总是最有效的选择。本文探讨了在 Bash 中完成此任务的更好方法。

命令 描述
${variable%.*} 参数扩展以从文件名中删除扩展名。
${variable##*.} 参数扩展以从文件名中提取扩展名。
awk -F. 将字段分隔符设置为句点,用于分割文件名。
OFS="." awk 中的输出字段分隔符,用于重建不带扩展名的文件名。
NF-- 将 awk 中的字段数量减少 1,有效地删除扩展名。
${BASH_REMATCH} 保存 Bash 中正则表达式匹配项的数组。
local variable 在 Bash 函数内声明具有局部作用域的变量。

Bash 解决方案的详细分解

提供的脚本提供了在 Bash 中分隔文件名及其扩展名的各种方法。第一个脚本使用 Bash 参数扩展。变量 ${FILE%.*} 通过剥离从最后一个句点到字符串末尾的所有内容来删除扩展名,而 ${FILE##*.} 通过获取最后一个句点之后的所有内容来捕获扩展。对于大多数文件名结构来说,此方法简单且高效。第二个脚本使用 awk,类 Unix 环境中强大的文本处理工具。通过使用将字段分隔符设置为句点 -F.,它允许将文件名分割成多个部分。输出字段分隔符, OFS=".",并减少字段数量 NF-- 是重新组合不带扩展名的文件名的技术。

第三个脚本在 Bash 中使用正则表达式,利用 ${BASH_REMATCH} 捕获正则表达式匹配中的组。该脚本使用一种模式将文件名分为两组:一组用于基本名称,一组用于扩展名。最后,自定义函数脚本将参数扩展逻辑封装在函数内,增强了代码的复用性和可读性。它用 local variable 声明将变量保留在函数内,防止较大脚本中出现意外的副作用。每种方法都展示了解决同一问题的不同方法,展示了 Bash 脚本的多功能性和强大功能。

在 Bash 中使用参数扩展

Bash 脚本

#!/bin/bash
# Script to extract filename and extension using parameter expansion
FILE="a.b.js"
FILENAME="${FILE%.*}"
EXTENSION="${FILE##*.}"
echo "Filename: $FILENAME"
echo "Extension: $EXTENSION"

使用 awk 分隔文件名和扩展名

使用 Awk 进行 Bash

#!/bin/bash
# Script to extract filename and extension using awk
FILE="a.b.js"
FILENAME=$(echo "$FILE" | awk -F. '{OFS="."; NF--; print $0}')
EXTENSION=$(echo "$FILE" | awk -F. '{print $NF}')
echo "Filename: $FILENAME"
echo "Extension: $EXTENSION"

在 Bash 中使用正则表达式

使用正则表达式编写 Bash 脚本

#!/bin/bash
# Script to extract filename and extension using regex
FILE="a.b.js"
[[ "$FILE" =~ (.*)\.(.*) ]]
FILENAME=${BASH_REMATCH[1]}
EXTENSION=${BASH_REMATCH[2]}
echo "Filename: $FILENAME"
echo "Extension: $EXTENSION"

在 Bash 中使用自定义函数

具有自定义函数的 Bash 脚本

#!/bin/bash
# Function to extract filename and extension
extract_filename_extension() {
  local file="$1"
  echo "Filename: ${file%.*}"
  echo "Extension: ${file##*.}"
}
# Call the function with a file
extract_filename_extension "a.b.js"

探索 Bash 中文件操作的替代方法

除了已经讨论的方法之外,Bash 中还有其他有用的技术来操作文件名和扩展名。其中一种方法涉及使用 basenamedirname 命令。 basename 可用于从路径中提取文件名,而 dirname 检索目录路径。将这些命令与参数扩展相结合可以有效地分离文件名和扩展名。例如,使用 basename "$FILE" ".${FILE##*.}" 从文件名中删除扩展名。当使用完整文件路径而不仅仅是文件名时,此方法特别有用。

另一种方法涉及使用 sed,一个强大的流编辑器,用于过滤和转换文本。通过设计适当的正则表达式, sed 可以隔离文件名和扩展名。例如,命令 echo "$FILE" | sed 's/\(.*\)\.\(.*\)/\1 \2/' 分割文件名和扩展名,将它们放在单独的捕获组中。这种技术很灵活,可以处理复杂的文件名结构。探索这些附加工具和方法可以扩展您在 Bash 中操作文件数据的能力,为各种脚本场景提供强大的解决方案。

有关 Bash 文件操作的常见问题

  1. 目的是什么 ${FILE%.*} 命令?
  2. 它通过删除最后一个句点之后的所有内容来从文件名中删除扩展名。
  3. 如何 ${FILE##*.} 指挥工作?
  4. 它通过获取文件名中最后一个句点之后的所有内容来提取扩展名。
  5. 什么是 awk -F. 在提供的脚本中做什么?
  6. 它将字段分隔符设置为句点,从而允许将文件名拆分为多个部分。
  7. 为什么使用 NF-- 在一个 awk 脚本?
  8. 它将字段数量减少一,有效地从文件名中删除扩展名。
  9. 正则表达式如何帮助提取文件名和扩展名?
  10. 它们允许模式匹配和分组,这可以隔离文件名的不同部分。
  11. 在 Bash 中使用自定义函数有什么好处?
  12. 自定义函数增强了代码的可重用性和可读性,使脚本更加模块化。
  13. 如何 basename 帮助处理文件名?
  14. 它从完整文件路径中提取文件名,并可选择删除扩展名。
  15. sed 用于文件名操作?
  16. 是的, sed 可以使用正则表达式来转换和隔离文件名的各个部分。

总结文件名和扩展名提取的解决方案

总之,在 Bash 中提取文件名和扩展名可以通过多种方法有效地实现,每种方法适合不同的需求和偏好。无论是使用参数扩展、awksed 还是自定义函数,这些技术都提供了灵活高效的解决方案。理解和利用这些命令可确保脚本能够正确处理具有多个句点和其他复杂性的文件名。