问候!
这是众所周知的 Bash 参数扩展模式:
${parameter#word} , ${parameter##word}
和
${parameter%word} , ${parameter%%word}
我需要从参数的开头切掉一部分,从参数的尾部切掉另一部分。你能给我一些建议吗?
问候!
这是众所周知的 Bash 参数扩展模式:
${parameter#word} , ${parameter##word}
和
${parameter%word} , ${parameter%%word}
我需要从参数的开头切掉一部分,从参数的尾部切掉另一部分。你能给我一些建议吗?
如果您使用的是 Bash 版本 >= 3.2,则可以使用正则表达式与捕获组匹配来检索一个命令中的值:
$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ [[ $path =~ ^.*/([^/]*)/.*$ ]]
$ echo ${BASH_REMATCH[1]}
ABC
这相当于:
$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ path=$(echo "$path" | sed 's|^.*/\([^/]*\)/.*$|\1|p')
$ echo $path
ABC
我不知道有一种简单的方法可以在不使用子外壳的情况下做到这一点,而为了提高效率,您可能希望避免这种情况。我只会使用:
> xx=hello_there
> yy=${xx#he}
> zz=${yy%re}
> echo ${zz}
llo_the
如果您不关心效率并且只想要一个单线:
> zz=$(echo ${xx%re} | sed 's/^he//')
> echo ${zz}
llo_the
请记住,第二种方法启动子外壳 - 如果您的脚本必须快速运行,我不会做很多事情。
该解决方案使用 Andrey 所要求的,并且不使用任何外部工具。策略:使用 % 参数扩展删除文件名,然后使用 ## 删除除最后一个目录之外的所有目录:
$ path=/path/to/my/last_dir/filename.txt
$ dir=${path%/*}
$ echo $dir
/path/to/my/last_dir
$ dir=${dir##*/}
$ echo $dir
last_dir
我强烈建议使用 bash 数组,因为它们的性能比正则表达式匹配快 3 倍多。
$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ IFS='/' arr=( $path )
$ echo ${arr[${#arr[@]}-2]}
ABC
/
这通过告诉 bash 数组的每个元素都由正斜杠分隔IFS='/'
。我们访问数组的倒数第二个元素,首先确定数组中有多少元素,${#arr[@]}
然后减去 2 并将其用作数组的索引。