给定一个字符串文件路径,例如/foo/fizzbuzz。酒吧,我如何使用bash提取只是fizzbuzz部分说的字符串?
当前回答
注意建议的perl解决方案:它删除第一个点之后的任何内容。
$ 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,如果你知道扩展名的话)要简单得多。
其他回答
纯bash,在两个独立的操作中完成:
从路径字符串中移除路径: 路径= / foo / bar / bim /巴兹/ file.gif 路径文件= $ {# # * /} #$file现在是file.gif 从路径字符串中移除扩展名: 基础= ${文件%。*} #${base}现在是“文件”。
basename会移除路径。它还将删除给定的后缀,如果它与文件的后缀匹配,但您需要知道为命令提供的后缀。否则,你可以用mv,用其他方法找出新名称。
perl -pe 's/\..*$//;s{^.*/}{}'
除了这个答案中使用的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*)
纯粹的bash方式:
~$ x="/foo/bar/fizzbuzz.bar.quux.zoom";
~$ y=${x/\/*\//};
~$ echo ${y/.*/};
fizzbuzz
这个功能在man bash的“参数扩展”中有解释。非bash方法有很多:awk、perl、sed等等。
EDIT:用于文件后缀中的点,不需要知道后缀(扩展名),但不用于名称本身中的点。