zsh:分割可能没有扩展名的路径

问题描述 投票:0回答:1

zsh
脚本中,我想将路径的文件名部分分成三部分:根、
.
分隔符(可能不存在)和扩展名。 另一个过程是修改这些碎片并将它们重新组合在一起。

确定输入路径是否有

.
比 预期的。 到目前为止,这是我找到的最好答案:

split=( "${pth:r}" "${${pth#${pth:r}}:+.}" "${pth:e}" )

它使用

zsh
r
e
参数标志来获取根和扩展; 这些部件运转良好。 中间组件更神秘的扩展是 本质上是比较路径根和原始路径。如果他们是 相同,则没有分隔符并且该值设置为空字符串。 否则它会被设置为句点。

似乎应该有一个比三部分嵌套更简单的选择 替代。 是否有一个标志或一些简单的东西我丢失了,或者是一个SO 我的搜索没有找到的帖子?


测试代码:

#!/bin/zsh
testsplit() {
  local pth=$1
  local split=( "${pth:r}" "${${pth#${pth:r}}:+.}" "${pth:e}" )

  print "input:    [$pth]"
  print "split[${#split}]:" "[${(@)^split}]"

  # tests: does rejoined path match input; is second element '.' or empty
  [[ ${(j::)split} == $pth && ${split[2]:-.} == '.' ]]
}
typeset -a testpaths=(
  "base.ext"
  "endsindot."
  "no_ext"
  "/a.b/c.d/e"
  "/a.b/c.d/e."
  "/a.b/c.d/e.f"
  "/has/s p aces  /before . after"
  $"/*/'and?[sdf]\n>\t\tpat.tern[^r\`ty&]///*/notreal.d"
)
integer ecount=0
print '.'
for p in ${testpaths}; do
  testsplit "$p"
  (($?)) && ((++ecount)) && print "=== ERROR ==="
  print '.'
done
print "Error count: [$ecount]."
((ecount)) && print "=== ERRORS FOUND ==="

输出:

.
input:    [base.ext]
split[3]: [base] [.] [ext]
.
input:    [endsindot.]
split[3]: [endsindot] [.] []
.
input:    [no_ext]
split[3]: [no_ext] [] []
.
input:    [/a.b/c.d/e]
split[3]: [/a.b/c.d/e] [] []
.
input:    [/a.b/c.d/e.]
split[3]: [/a.b/c.d/e] [.] []
.
input:    [/a.b/c.d/e.f]
split[3]: [/a.b/c.d/e] [.] [f]
.
input:    [/has/s p aces  /before . after]
split[3]: [/has/s p aces  /before ] [.] [ after]
.
input:    [$/*/'and?[sdf]
>       pat.tern[^r`ty&]///*/notreal.d]
split[3]: [$/*/'and?[sdf]
>       pat.tern[^r`ty&]///*/notreal] [.] [d]
.
Error count: [0].
path zsh filenames
1个回答
1
投票

似乎应该有一个比三部分嵌套替换更简单的选择。

也许有,但不幸的是,确实没有。 🙂

这是我的做法,但同样,嵌套替换是不可避免的:

% split() { 
  local split=( "$1:r" "${${1#$1:r}[1]}" "$1:e" )
  print "${(q@)split}"
}
% split foo.orig.c 
foo.orig . c
% split dir.c/foo 
dir.c/foo '' ''                                                                                                                                                                     
© www.soinside.com 2019 - 2024. All rights reserved.