如何从zsh变量中提取第n个模式?

时间:2014-01-03 17:00:27

标签: zsh

我有一个由下划线分隔的变量,它对不同的信息位进行编码,例如:

my_variable="john_smith_cambridge_MA_65_male"

如果location应该是第三和第四个字段的组合,我想我可以做

location=${(j._.)${${(s._.)my_variable}[3,4]}}
echo $location # cambridge_MA

但我想知道是否有比分割然后加入更简单的语法。

编辑:经过一些研究,我发现我可以使用反向引导标志(#b)

if [[ $my_variable == (#b)([^_]#)_([^_]#)_([^_]#)_([^_]#)_([^_]#)_([^_]#) ]]; then
    echo ${my_variable[$mbegin[3], $mend[4]]} # cambridge_MA
fi
虽然设置那个长正则表达式似乎有点麻烦。

还有其他想法吗?

1 个答案:

答案 0 :(得分:1)

分裂和加入对我来说似乎是最明智的方法。您有一个操作来指定如何拆分字符串,还有一个操作来指定要保留的字段。

如果您打算使用多个字段,请一次性拆分成一个数组。

details=("${(@s:_:)my_variable}")
location=${(j:_:)details[3,4]}

要提取固定位置的字段,您还可以使用前缀和后缀剥离:

city=${${my_variable#*_*_}%%_*}

但是这两个操作只是提取一个字段,除非你知道字段数,否则它不会干净地概括为多个连续字段,在这种情况下你可以像剥离前缀一样去除后缀。

location=${${my_variable#*_*_}%_*_*}

虽然您可以使用I参数扩展标志在简单搜索中组合这两者,但这需要您将搜索锚定在分隔符上。这有效,但它比分裂和加入要麻烦得多。

setopt extended_glob
echo ${${(MSI:2:)my_variable##_[^_]##_[^_]##}#_}