我该如何在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 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
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
mv "$file" "${file#XY\ TD-}"
。 - tripleeels
。我只是为了让新手感到熟悉,并稍后提醒他们注意。但这并不是非常重要的。 - Shahbazfiles=(*);echo $files|sed -e 's/^new.//'
。为什么?我使用zsh。 - Timobrew install rename
然后在目录中运行下面的命令,从所有文件中删除“prefix-”前缀:
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)
<()
是bash的扩展,不包含在POSIX sh中。您可以使用形式为find ... | while
的管道替换它。-print0
是GNU扩展,不包含在POSIX find中。POSIX find没有等效的方法来定位文件,这对于包含换行符的名称是安全的,因此很难进行替换。
XY TD-
是“文件名前缀”,他想要删除它。那么“XY”可能不是一个shell命令。 - ArjunShankarfor file in *; do echo mv "$file" "${file#*-}"; done
。当然,在预览看起来不错时,请删除echo
。这类似于这个答案。 - Henke