如何从Bash中的pathstring中删除文件后缀和path部分?

给定一个string文件path如“/foo/fizzbuzz.bar”,我将如何使用bash来提取所述string的“fizzbuzz”部分?

以下是如何使用Bash中的#和%运算符来完成的。

$ x="/foo/fizzbuzz.bar" $ y=${x%.bar} $ echo ${y##*/} fizzbuzz 

${x%.bar}也可以是${x%.*}来删除点或${x%%.*}之后的所有内容,以删除第一个点之后的所有内容。

例:

 $ x="/foo/fizzbuzz.bar.quux" $ y=${x%.*} $ echo $y /foo/fizzbuzz.bar $ y=${x%%.*} $ echo $y /foo/fizzbuzz 

文档可以在Bash手册中find。 查找${parameter%word}${parameter%%word}尾部分匹配部分。

看一下basename命令:

 NAME=`basename /foo/fizzbuzz.bar .bar` 

纯粹的打击,在两个单独的行动:

  1. 从pathstring中删除path:

     path=/foo/bar/bim/baz/file.gif file=${path##*/} #$file is now 'file.gif' 
  2. 从pathstring中删除扩展名:

     base=${file%.*} #${base} is now 'file'. 

纯粹的bash方式:

 ~$ x="/foo/bar/fizzbuzz.bar.quux.zoom"; ~$ y=${x/\/*\//}; ~$ echo ${y/.*/}; fizzbuzz 

该function在“参数扩展”下的man bash中解释。 非bash方式比比皆是:awk,perl,sed等。

编辑:与文件后缀中的点一起使用,不需要知道后缀(扩展名),但不能名称本身中使用点。

基本名称和dirname函数是你所追求的:

 mystring=/foo/fizzbuzz.bar echo basename: $(basename $mystring) echo basename + remove .bar: $(basename $mystring .bar) echo dirname: $(dirname $mystring) 

已输出:

 basename: fizzbuzz.bar basename + remove .bar: fizzbuzz dirname: /foo 

使用基本名称我使用以下来实现这一点:

 for file in *; do ext=${file##*.} fname=`basename $file $ext` # Do things with $fname done; 

这不需要关于文件扩展名的先验知识,即使你有一个文件名的文件名(在它的扩展名之前),它也可以工作。 它确实需要程序basename ,但是这是GNU coreutils的一部分,所以它应该随任何发行版一起提供。

 perl -pe 's/\..*$//;s{^.*/}{}' 

使用basename假定你知道文件扩展名是什么,不是吗?

我相信各种正则expression式的build议不能处理包含多个“。”的文件名。

以下似乎应付双重点。 噢,包含“/”的文件名本身(仅用于踢)

用帕斯卡的话来说,“对不起,这个剧本太长了,我没有时间把它缩短”

 #!/usr/bin/perl $fullname = $ARGV[0]; ($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/; ($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/; print $basename . "\n"; 

如果你不能像其他文章中build议的那样使用basename,你总是可以使用sed。 这是一个丑陋的例子。 这不是最大的,但它通过提取想要的string并用想要的stringreplaceinput来工作。

 echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g' 

这将得到你的输出

fizzbuzz

小心build议的perl解决scheme:它在第一个点之后删除任何东西。

 $ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}' some 

如果你想用Perl来做到这一点,

 $ echo some.file.with.dots | perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}' some.file.with 

但是,如果您使用Bash,那么使用y=${x%.*} (或basename "$x" .ext如果您知道扩展名)的解决scheme要简单得多。

结合最高评分的答案和第二最高评分的答案来获取没有完整path的文件名:

 $ x="/foo/fizzbuzz.bar.quux" $ y=(`basename ${x%%.*}`) $ echo $y fizzbuzz 

基地名称,删除path。 它也将删除后缀,如果给出,如果它匹配文件的后缀,但你需要知道后缀给命令。 否则,你可以使用MV,并找出新的名字应该是一些其他的方式。

您可以在Bash手册中find信息,在尾部匹配部分查找${parameter%word}${parameter%%word}