前言:
当前你们对“java文件后缀名获取”大概比较注意,我们都需要分析一些“java文件后缀名获取”的相关资讯。那么小编同时在网络上搜集了一些关于“java文件后缀名获取””的相关知识,希望朋友们能喜欢,姐妹们快快来学习一下吧!如何使用参数扩展?如何获取子字符串?如何获取没有扩展名的文件,或者只获取文件的扩展名?有哪些好的方法可以做到basename和dirname?
参数扩展是一个重要的主题,涉及将变量或特殊参数替换为其对应的值。在类似Bash的Bourne shell中,参数扩展是解引用(引用)变量的主要方式之一,并且还提供了方便的值操作功能。请记住,在进行扩展时要给定适当的引号。
首先,我们来看一组从参数开头或末尾删除子字符串的功能示例。下面是一个使用参数扩展实现类似主机名(由点分隔的组件)的示例:
parameter result----------- ------------------------------$name polish.ostrich.racing.champion${name#*.} ostrich.racing.champion${name##*.} champion${name%%.*} polish${name%.*} polish.ostrich.racing
此外,接下来我们以典型文件名为例展示参数扩展的使用:
parameter result----------- --------------------------------------------------------$file /usr/share/java-1.4.2-sun/demo/applets/Clock/Clock.class${file#*/} usr/share/java-1.4.2-sun/demo/applets/Clock/Clock.class${file##*/} Clock.class${file%%/*}${file%/*} /usr/share/java-1.4.2-sun/demo/applets/Clock
需要注意的是,参数扩展不支持嵌套。如果需要进行多个扩展步骤,请使用一个变量来保存第一个扩展结果:
# foo holds: key="some value"bar=${foo#*=\"} bar=${bar%\"*}# now bar holds: some value
下面是一些更多示例
${string:2:1} # 字符串 string 的第三个字符(0、1、2 表示第三个字符)${string:1} # 从字符串 string 的第二个字符开始的子串 # 注意:这等价于 ${string#?}${string%?} # 删除字符串 string 的最后一个字符后的子串${string: -1} # 字符串 string 的最后一个字符${string:(-1)} # 字符串 string 的最后一个字符,备选语法 # 注意:string:-1 表示另一种完全不同的含义;见下文。${file%.mp3} # 去掉文件名中的 .mp3 扩展名 # 在循环中非常有用,例如:for file in *.mp3; do ...${file%.*} # 去掉文件名中的最后一个扩展名${file%%.*} # 去掉文件名中的所有扩展名${file##*.} # 只保留文件名中的扩展名,假设存在一个扩展名。如果不存在,则会展开为:$file文件名操作示例
这里是一种符合POSIX标准的方式,可以提取完整路径名中的目录组件、文件名、仅扩展名、没有扩展名的文件名("stub"),在"stub"末尾出现的任何数值部分(忽略文件名中间的数字),对该数字进行算术操作(例如递增一),并重新组装整个文件名,在文件名前添加前缀,并用另一个数字替换文件名中的数字。
FullPath=/path/to/name4afile-009.ext # result: # /path/to/name4afile-009.extFilename=${FullPath##*/} # name4afile-009.extPathPref=${FullPath%"$Filename"} # /path/to/FileStub=${Filename%.*} # name4afile-009FileExt=${Filename#"$FileStub"} # .extFnumPossLeading0s=${FileStub##*[![:digit:]]} # 009FnumOnlyLeading0s=${FnumPossLeading0s%%[!0]*} # 00FileNumber=${FnumPossLeading0s#"$FnumOnlyLeading0s"} # 9NextNumber=$(( FileNumber + 1 )) # 10NextNumberWithLeading0s=$(printf "%0${#FnumPossLeading0s}d" "$NextNumber") # 010FileStubNoNum=${FileStub%"$FnumPossLeading0s"} # name4afile-NewFullPath=${PathPref}New_${FileStubNoNum}${NextNumberWithLeading0s}${FileExt} # Final result is: # /path/to/New_name4afile-010.ext
请注意,如果 $FullPath 是 SomeFilename.ext 或其他不带斜线的路径名,则尝试使用 PathPref="${FullPath%/*}" 获取路径名中的目录组件时,将无法返回空字符串。同样,使用 FileExt="${Filename#*.}"获取文件扩展名时,如果 $Filename 没有点(因此也没有扩展名),也会返回空字符串。
还要注意的是,为了进行算术运算,必须去掉 $FileNumber 的前导零,否则数字将被解释为八进制。另外,也可以添加 10# 前缀,强制以 10 为底。在上面的例子中,尝试计算 $(( FnumPossLeading0s + 1 )) 结果会出错,因为 "00809 "不是一个有效的数字。如果我们使用 "00777",就不会出错,但 $(( FnumPossLeading0s + 1 )) 的结果将是 "1000"(因为八进制 777 + 1 是八进制 1000),这可能不是我们想要的结果。
在变量赋值中不需要加引号,因为 WordSplitting 不会发生。另一方面,在参数扩展中引用的变量需要加引号(例如,在PathPref=${FullPath%"$Filename"}中引用 $Filename ),否则文件名中的任何 * 或 ? 或其他此类字符都会错误地成为参数扩展的一部分(例如,如果星号是文件名中的第一个字符 ,则可以尝试 FullPath="dir/*filename" )。
数组上的参数扩展
BASH 数组非常灵活,因为它们与其他 shell 扩展很好地结合在一起。任何可以在标量或单个数组元素上执行的参数扩展,都可以同样适用于整个数组或位置参数集,这样所有成员都会一次性扩展,可能还会在每个元素上映射额外的操作。这可以通过扩展 @、、arrayname[@] 和 arrayname[] 形式的参数来实现。这些特殊扩展参数必须正确加引号--几乎总是双引号(如"{cmd[@]}")--这样,无论其内容如何,成员都会按字面意思作为单个单词处理。例如,arr=("${list[@]}" foo) 可以正确处理 list 数组中的所有元素。
首先是扩展:
$ a=(alpha beta gamma) # 通过复合赋值将值分配给基本数组$ echo "${a[@]#a}" # 去掉每个元素开头的 'a'lpha beta gamma$ echo "${a[@]%a}" # 去掉每个元素结尾的 'a'alph bet gamm$ echo "${a[@]//a/f}" # 字符串替换,将每个元素中的 'a' 替换为 'f'flphf betf gfmmf
以下扩展(在开头或结尾处替换)对下一部分非常有用:
$ echo "${a[@]/#a/f}" # substitute a for f at startflpha beta gamma$ echo "${a[@]/%a/f}" # at endalphf betf gammf
我们使用它们来为列表中的每个成员添加前缀或后缀:
$ echo "${a[@]/#/a}" # 在每个元素的开头附加字符 'a'aalpha abeta agamma # (感谢 floyd-n-milan 提供此注释)$ echo "${a[@]/%/a}" # 在每个元素的结尾附加字符 'a'alphaa betaa gammaa
它的工作原理是用我们希望附加的值代替开头或结尾的空字符串。
最后,举例说明如何在脚本中使用此功能,比如为每个目标添加用户自定义的前缀:
$ PFX=inc_$ a=("${a[@]/#/$PFX}")$ echo "${a[@]}"inc_alpha inc_beta inc_gamma
如你所想,这非常有用,因为它可以省去对数组中每个成员的循环。
特殊参数 @ 也可以用作数组,用于参数扩展:
${@:(-2):1} # 第二个到最后${@: -2:1} # 另一种可选择的语法
但不能使用 ${@:-2:1}(注意空格),因为这与下一节描述的语法相冲突。
可移植性
最初的 Bourne shell(第 7 版 Unix)只支持非常有限的参数扩展选项:
${var-word} # 如果 var 已定义,则使用 var;否则使用 "word"${var+word} # 如果 var 已定义,则使用 "word";否则什么都不做${var=word} # 如果 var 已定义,则使用 var;否则使用 "word" 并且... # 还要将 "word" 分配给 var${var?error} # 如果 var 已定义,则使用 var;否则输出 "error" 并退出
这些是唯一完全可移植的扩展。
POSIX shells(以及 KornShell 和 BASH)提供了这些扩展,另外还有一个小变种:
${var:-word} # 如果 var 已定义并且不为空,则使用 var;否则使用 "word"类似地,${var:+word} 等也是类似的用法。
POSIX、Korn(所有版本)和 Bash 均支持 ${var#word}、${var%word}、${var##word} 和 ${var%%word} 扩展。
ksh88 不支持 ${var/replace/with} 或 ${var//replace/all},但 ksh93 和 Bash 支持。
ksh88 不支持数组的花式扩展(例如,${a[@]%.gif}),但 ksh93 和 Bash 支持。
ksh88 不支持 arr=(...) 类型的复合赋值。要么使用 set -A arrayname -- elem1 elem2 ...,要么使用 arr[0]=val1 arr[1]=val2 ...为每个元素单独赋值。
学习更多shell最佳实践
如果您觉得文章内容对你有一点帮助可以关注我,我在头条平台会持续分享更多实用的shell技巧和最佳实践,如果想系统的快速学习shell的各种高阶用法和生产环境避坑指南可以看看《shell脚本编程最佳实践》专栏,专栏里有更多的实用小技巧和脚本代码分享。
标签: #java文件后缀名获取