37

如何删除 Bash 中的文件名前缀,如下例所示:

XY TD-11212239.pdf

要得到

11212239.pdf

即,删除XY TD-

4

5 回答 5

44

您说POSIX shell 将包括 BASH、Kornshell、Ash、Zsh 和 Dash。幸运的是,所有这些 shell 都会对变量值进行模式过滤。

当您*在 Unix/Linux 命令行中指定文件时使用的模式是:

$ ls *.sh  # Lists all files with a `.sh` suffix

这些 POSIX shell 使用四种不同的模式过滤:

  • ${var#pattern}- 从左侧删除与模式匹配的最小字符串。
  • ${var##pattern}- 从左侧删除与模式匹配的最大字符串。
  • ${var%pattern}- 从右侧删除与模式匹配的最小字符串。
  • ${var%%pattern}- 从右侧删除与模式匹配的最大字符串。

这里有一些例子:

foo="foo-bar-foobar"
echo ${foo#*-}   # echoes 'bar-foobar'  (Removes 'foo-' because that matches '*-')
echo ${foo##*-}  # echoes 'foobar' (Removes 'foo-bar-')
echo ${foo%-*}   # echoes 'foo-bar'
echo ${foo%%-*}  # echoes 'foo'

您并没有真正解释您想要什么,也没有包含任何代码示例,因此很难想出可以满足您需求的东西。但是,使用模式过滤,您可能可以准确地确定您想要对文件名做什么。

file_name="XY TD-11212239.pdf"
mv "$file_name" "${file_name#*-}" # Removes everything from up to the first dash
于 2014-08-27T21:05:57.297 回答
30

您提供的信息很少,但假设您在 bash 中执行此操作,并且有一个需要删除其前缀的文件列表,您可以通过管道将该列表sed

例如:

./generate_your_list_of_files | sed -e 's/^prefix//'

或者如果您的文件列表是空格分隔的:

echo TD-file1 TD-file2.x.yt TD-file3-beep | sed -e 's/\<TD-//g'

第一个匹配行首的前缀并将其删除。第二个匹配TD-(或您要替换的任何其他前缀)仅当它发生在单词的开头并在所有行的所有匹配中替换它时。但是这可能会变得很危险,例如像TD-file\ that\ TD-contains\ space.txt变成这样的文件file\ that\ contains\ space.txt

作为旁注,不要使用ls. 这是一个可怕的错误。如果您需要获取要使用的文件列表并在多个地方引用,我建议将它们放在一个数组中:

files=(*)

然后使用这个数组。


由于受欢迎的要求(下面的单个评论),这里是如何重命名目录中以XY TD-删除前缀开头的所有文件(感谢@tripleee):

for file in prefix*;
do
    mv "$file" "${file#XY TD-}"
done
于 2012-05-10T14:26:22.623 回答
16

您还可以使用重命名工具

用自制软件安装它

brew install rename

然后从目录中运行以下命令以从所有文件中删除“前缀-”

rename -d prefix- *

于 2014-08-27T19:54:34.930 回答
6

除了其他答案中显示的子字符串提取之外,您还可以使用子字符串替换。给定文件:

fn="XY TD-11212239.pdf"

然后子字符串替换:

fn_new=${fn//*TD-/}

也会做你想做的。

于 2014-08-27T20:50:27.847 回答
2
$ s='XY TD-11212239.pdf'
$ echo "${s#XY TD-}"
11212239.pdf

如果您的目标是执行批量重命名:

while IFS= read -r -d '' filename; do
  mv "$filename" "${filename#XY TD-}"
done < <(find . -type f -name 'XY TD-*' -print0)

请注意,这<()是 POSIX sh 中不存在的 bash 扩展。您可以将其替换为表单的管道find ... | while

同样,-print0在 POSIX 查找中不存在 GNU 扩展。POSIX find 没有提供等效的方法来定位包含换行符的名称安全的文件,因此难以替换。

于 2014-08-27T19:58:53.040 回答