删除 Bash 中的文件名前缀,如以下示例所示:
XY TD-11212239.pdf
要得到
11212239.pdf
即,删除XY TD-
?
你说的是POSIX shell,其中包括BASH,Kornshell,Ash,Zsh和Dash。幸运的是,所有这些 shell 都对变量值进行模式过滤。
模式是您在 Unix/Linux 命令行上指定具有*
等内容的文件时使用的模式:
$ ls *.sh # Lists all files with a `.sh` suffix
这些 POSIX 外壳使用四种不同的模式过滤:
-
${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
您提供的信息很少,但是假设您在 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
您也可以使用重命名工具
使用自制软件安装它
brew install rename
然后从目录中运行以下命令以从所有文件中删除"前缀-">
rename -d prefix- *
除了其他答案中显示的子字符串提取外,您还可以使用子字符串替换。给定文件:
fn="XY TD-11212239.pdf"
然后子字符串替换:
fn_new=${fn//*TD-/}
也会做你想做的事。
$ 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 没有提供等效的方法来查找文件,这对于包含换行符的名称是安全的,因此难以替换。