Extract file basename without path and extension in bash
给定的文件名如下:
1 2 | /the/path/foo.txt bar.txt |
我希望得到:
1 2 | foo bar |
为什么这样不行?
1 2 3 4 5 6 | #!/bin/bash fullfile=$1 fname=$(basename $fullfile) fbname=${fname%.*} echo $fbname |
正确的方法是什么?
您不必调用外部
1 2 3 4 5 6 7 8 | $ s=/the/path/foo.txt $ echo ${s##*/} foo.txt $ s=${s##*/} $ echo ${s%.txt} foo $ echo ${s%.*} foo |
请注意,此解决方案应适用于最近(2004年后)所有符合POSIX的shell(如
来源:shell命令语言2.6.2参数扩展
关于bash字符串操作的更多信息:http://tldp.org/ldp/lg/issue18/bash.html
basename命令有两种不同的调用;一种是只指定路径,在这种情况下,它会给出最后一个组件,而在另一种情况下,它还会给出一个将要删除的后缀。因此,您可以使用第二次调用basename来简化示例代码。此外,请注意正确引用以下内容:
1 2 | fbname=$(basename"$1" .txt) echo"$fbname" |
basename和cut的组合效果很好,即使是像
1 | fbname=$(basename"$fullfile" | cut -d. -f1) |
如果这个解决方案比bash参数扩展需要更少的算术能力,那就很有趣了。
纯
1 2 | s=/the/path/foo.txt echo ${s//+(*\/|.*)} |
输出:
1 | foo |
注:
1 | shopt -s extglob |
走过
相关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 ${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pat‐
tern just as in pathname expansion. Parameter is expanded and
the longest match of pattern against its value is replaced with
string. If pattern begins with /, all matches of pattern are
replaced with string. Normally only the first match is
replaced. If pattern begins with #, it must match at the begin‐
ning of the expanded value of parameter. If pattern begins with
%, it must match at the end of the expanded value of parameter.
If string is null, matches of pattern are deleted and the / fol‐
lowing pattern may be omitted. If parameter is @ or *, the sub‐
stitution operation is applied to each positional parameter in
turn, and the expansion is the resultant list. If parameter is
an array variable subscripted with @ or *, the substitution
operation is applied to each member of the array in turn, and
the expansion is the resultant list.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol‐
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
以下是一句话:
我需要这个,就像邦邦和W4etwetwet要求的那样。
以下是获取文件名或扩展名的另一种(更复杂)方法,首先使用
1 2 | filename=`rev <<<"$1" | cut -d"." -f2- | rev` fileext=`rev <<<"$1" | cut -d"." -f1 | rev` |
如果您想使用Windows文件路径(在cygwin下)进行良好的播放,也可以尝试以下操作:
1 | fname=${fullfile##*[/|\\]} |
在Windows上使用bash时,这将解释反斜杠分隔符。
只是我想出的一个替代方法来提取一个扩展,使用这个线程中的文章和我自己更熟悉的小知识库。
1 | ext="$(rev <<<"$(cut -f"1" -d"." <<<"$(rev <<<"file.docx")")")" |
注意:请建议我使用报价单;它对我有效,但我可能会错过一些关于它们正确使用的内容(我可能使用太多)。
使用basename命令。它的主页在这里:http://unixhelp.ed.ac.uk/cgi/man-cgi?基名