如何从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`
纯粹的打击,在两个单独的行动:
-
从pathstring中删除path:
path=/foo/bar/bim/baz/file.gif file=${path##*/} #$file is now 'file.gif'
-
从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}
。