使用 bash 变量替换代替 cut/awk

bon*_*onh 3 bash awk cut

我可以使用 bash 变量替换来提取基于分隔符的变量吗?我正在尝试获取文件名的直接目录名(在本例中为foo)。

$ filename=./foo/bar/baz.xml
Run Code Online (Sandbox Code Playgroud)

我知道我可以做类似的事情

echo $filename | cut -d '/' -f 2
Run Code Online (Sandbox Code Playgroud)

或者

echo $filename | awk -F '/' '{print $2}'
Run Code Online (Sandbox Code Playgroud)

但是fork awk/ cutfor多个文件名变得很慢。

我使用我的真实文件对各种解决方案进行了一些分析:

回声| 切:

real    2m56.805s
user    0m37.009s
sys     1m26.067s
Run Code Online (Sandbox Code Playgroud)

回声| awk:

real    2m56.282s
user    0m38.157s
sys     1m31.016s
Run Code Online (Sandbox Code Playgroud)

@steeldriver 的变量替换/shell 参数扩展:

real    0m0.660s
user    0m0.421s
sys     0m0.235s
Run Code Online (Sandbox Code Playgroud)

@jai_s 的 IFS 争论:

real    1m26.243s
user    0m13.751s
sys     0m28.969s
Run Code Online (Sandbox Code Playgroud)

这两个建议都是对我现有想法的巨大改进,但变量替换速度最快,因为它不需要分叉任何新流程。

ste*_*ver 10

您可以删除匹配的最短前导子字符串 */

tmp="${filename#*/}"
Run Code Online (Sandbox Code Playgroud)

然后删除匹配的最长尾随子字符串 /*

echo "${tmp%%/*}"
Run Code Online (Sandbox Code Playgroud)