给定一个字符串文件路径,例如/foo/fizzbuzz。酒吧,我如何使用bash提取只是fizzbuzz部分说的字符串?
当前回答
看看basename命令:
NAME="$(basename /foo/fizzbuzz.bar .bar)"
指示它删除后缀.bar,结果是NAME=fizzbuzz
其他回答
使用basename假设您知道文件扩展名是什么,不是吗?
而且我相信各种正则表达式建议不能处理包含多个“”的文件名。
下面的内容似乎可以解决双点问题。哦,还有本身包含“/”的文件名(只是为了好玩)
用帕斯卡尔的话来说,“对不起,这个脚本太长了。我没有时间把它缩短。”
#!/usr/bin/perl
$fullname = $ARGV[0];
($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
print $basename . "\n";
使用basename我使用以下方法来实现这一点:
for file in *; do
ext=${file##*.}
fname=`basename $file $ext`
# Do things with $fname
done;
这不需要对文件扩展名的先验知识,即使你的文件名中有点(在它的扩展名前面)也可以工作;虽然它确实需要程序基名,但这是GNU coreutils的一部分,所以它应该随任何发行版一起发布。
如果你不能像其他文章中建议的那样使用basename,你总是可以使用sed。这里有一个(丑陋的)例子。它不是最好的,但它的工作原理是提取所需的字符串并将输入替换为所需的字符串。
echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g'
哪一个会得到输出
嘶嘶声
basename和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
除了这个答案中使用的POSIX符合语法外,
basename string [suffix]
就像在
basename /foo/fizzbuzz.bar .bar
GNU basename支持另一种语法:
basename -s .bar /foo/fizzbuzz.bar
同样的结果。区别和优势在于-s意味着-a,它支持多个参数:
$ basename -s .bar /foo/fizzbuzz.bar /baz/foobar.bar
fizzbuzz
foobar
这甚至可以通过使用-z选项将输出与NUL字节分开来实现文件名安全,例如对于这些包含空格,换行符和glob字符(由ls引用)的文件:
$ ls has*
'has'$'\n''newline.bar' 'has space.bar' 'has*.bar'
读入数组:
$ readarray -d $'\0' arr < <(basename -zs .bar has*)
$ declare -p arr
declare -a arr=([0]=$'has\nnewline' [1]="has space" [2]="has*")
readarray -d要求Bash 4.4或更新版本。对于旧版本,我们必须循环:
while IFS= read -r -d '' fname; do arr+=("$fname"); done < <(basename -zs .bar has*)