eth*_*day 2 bash shell parameter-expansion
我想使用参数扩展获取foo给定文件的直接父目录的名称,例如给定/home/blah/foo/bar.txt.现在我可以用两行来做:
f="/home/blah/foo/bar.txt"
dir_name="${f%/*}"
immediate_parent="${dir_name##*/}"
Run Code Online (Sandbox Code Playgroud)
但我对参数扩展很新,所以我认为这可以进行优化.有没有办法只用一行呢?
您不能使用单个参数扩展来执行此操作,但您可以使用=~Bash的正则表达式匹配运算符:
[[ $f =~ ^.*/(.+)/.+$ ]] && immediate_parent=${BASH_REMATCH[1]}
Run Code Online (Sandbox Code Playgroud)
注意:假设具有至少2个组件的绝对路径.
如果可以接受调用外部实用程序,则awk提供可能更简单的替代方法:
immediate_parent=$(awk -F/ '{ print $(NF-1) }' <<<"$f")
Run Code Online (Sandbox Code Playgroud)
至于为什么单个参数扩展无法完成:
参数扩展允许汽提或者前缀(#/ ##)或后缀(%/ %%从一个变量值),但不是两者.
使用单个参数扩展,只能通过字符位置和长度来提取内部子字符串 ; 例如,基于样本输入的硬编码解决方案将是:immediate_parent=${f:11:3}
您可以使用算术表达式甚至命令替换作为参数扩展参数,但是如果我们尝试的话,这种方法的无意义 - 至少在这种情况下 - 变得明显; 注意嵌入式命令替换 - 第一个计算字符位置,第二个计算长度:
immediate_parent=${f:$(d=${f%/*/*}; printf %s ${#d})+1:$(awk -F/ '{ print length($(NF-1)) }' <<<"$f")}
Run Code Online (Sandbox Code Playgroud)