bash 如何使用 Posix shell 删除文件名前缀

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10535985/
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-09 22:02:57  来源:igfitidea点击:

How to remove filename prefix with a Posix shell

bashshellprefix

提问by hamid

How can I remove the filename prefix in Bash as in the following example:

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

XY TD-11212239.pdf

to get

要得到

11212239.pdf

i.e, remove XY TD-?

即,删除XY TD-

回答by Shahbaz

You have given very little information, but assuming you are doing this in bash, and have a list of files whose prefix needs to be removed, you can pipe the list through sed:

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

For example:

例如:

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

or if your list of files are space separated:

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

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

The first one matches prefix in the beginning of the line and removes it. The second one matches TD-(or any other prefix you want to substitute) only when it happens at the beginning of a word and replaces it in all the matches in all the lines. This couldget dangerous though, for example a file like TD-file\ that\ TD-contains\ space.txtbecomes file\ that\ contains\ space.txt

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

As a side note, don't get your list of files using ls. That's a horrible mistake. If you need to get a list of files to work with and refer to in more than a single place, I'd suggest putting them in an array:

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

files=(*)

and then work with this array.

然后使用这个数组。



Due to popular requests (the single comment below), here is how to rename all files in the directory that start with XY TD-such that the prefix is removed (Thanks to @tripleee):

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

for file in prefix*;
do
    mv "$file" "${file#XY TD-}"
done

回答by David W.

You said POSIXshells which would include BASH, Kornshell, Ash, Zsh, and Dash. Fortunately, all of these shells do pattern filteringon variable values.

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

Patterns are what you use when you specify files with things like *on the Unix/Linux command line:

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

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

These POSIX shells use four different pattern filtering:

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

  • ${var#pattern}- Removes smallest string from the left side that matches the pattern.
  • ${var##pattern}- Removes the largest string from the left side that matches the pattern.
  • ${var%pattern}- Removes the smallest string from the right side that matches the pattern.
  • ${var%%pattern}- Removes the largest string from the right side that matches the pattern.
  • ${var#pattern}- 从左侧删除与模式匹配的最小字符串。
  • ${var##pattern}- 从左侧删除与模式匹配的最大字符串。
  • ${var%pattern}- 从右侧删除与模式匹配的最小字符串。
  • ${var%%pattern}- 从右侧删除与模式匹配的最大字符串。

Here are a few examples:

这里有一些例子:

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'

You didn't really explain what you want, and you didn't include any code example, so it's hard to come up with something that will do what you want. However, using pattern filtering, you can probably figure out exactly what you want to do with your file names.

你没有真正解释你想要什么,也没有包含任何代码示例,所以很难想出一些可以做你想做的事情。但是,使用模式过滤,您可能可以准确地弄清楚您想对文件名做什么。

file_name="XY TD-11212239.pdf"
mv "$file_name" "${file_name#*-}" # Removes everything from up to the first dash

回答by Ken Prince

You can also use the renametool

您也可以使用重命名工具

Install it with homebrew

用自制软件安装它

brew install rename

brew install rename

Then run the command below from within the directory to remove the "prefix-" from all files

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

rename -d prefix- *

rename -d prefix- *

回答by David C. Rankin

In addition to substring extraction shown in other answers, you can also make use of substring replacement. Given the file:

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

fn="XY TD-11212239.pdf"

Then substring replacement of:

然后子串替换:

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

Will also do what you want.

也会做你想做的。

回答by Charles Duffy

$ s='XY TD-11212239.pdf'
$ echo "${s#XY TD-}"
11212239.pdf

If your goal is to perform a mass rename:

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

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

Note that <()is a bash extension not present in POSIX sh. You can replace it with a pipeline of the form find ... | while.

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

Similarly, -print0is a GNU extension not present in POSIX find. POSIX find provides no equivalent way to locate files which is safe for names containing newlines, making it difficult to replace.

类似地,-print0是 POSIX 中不存在的 GNU 扩展。POSIX find 没有提供定位文件的等效方法,这对于包含换行符的名称是安全的,因此难以替换。