5月29日 01:19
Shell 脚本中常用的字符串操作有哪些?
Shell 字符串操作全部通过 ${} 参数展开完成,无需外部命令。拼接直接并排书写即可:"$a$b" 或 "${a}_${b}"。长度用 ${#var}。截取用 ${var:offset:length},支持负偏移从末尾取。最常用的模式删除:${var#pattern} 删最短前缀、${var##pattern} 删最长前缀、${var%pattern} 删最短后缀、${var%%pattern} 删最长后缀——这是提取文件名、路径、扩展名的标准做法。替换用 ${var/pattern/replacement} 替首次、${var//pattern/replacement} 替全部。
追问
1. # 和 ## 删除前缀有什么区别?% 和 %% 呢?
从左删最短匹配,## 删最长匹配。以 path=/a/b/c.txt 为例,${path#/} 得 a/b/c.txt(删到第一个 /),${path##/} 得 c.txt(删到最后一个 /)。% 和 %% 从右删,逻辑对称。记忆:# 在键盘左边删左边,% 在右边删右边。
2. ${var:offset:length} 的 offset 是从 0 还是 1 开始?负数偏移要注意什么? offset 从 0 开始。负偏移表示从末尾计数,但冒号后必须加空格:${var: -3} 取末尾3个字符,不加空格会被误认为默认值语法 ${var:-3}。
3. 怎么提取文件路径中的目录、文件名和扩展名? dir=${path%/}、name=${path##/}、ext=${path##.}、base=${name%.}。这比 dirname/basename 命令更快,因为不需要 fork 子进程。
4. 字符串替换能用正则吗? ${var/pattern/replacement} 的 pattern 是 glob 通配符(* ? [abc]),不是正则。需要正则匹配要用 [[ $var =~ regex ]] 配合 BASH_REMATCH 数组,或调用 sed/awk。
写段代码
bashpath="/data/logs/app.access.log" filename=${path##*/} # app.access.log dir=${path%/*} # /data/logs base=${filename%.*} # app.access ext=${filename##*.} # log echo "$dir / $base / $ext"