如何通过可变数量的定界符获取子字符串中字符串的最后一部分

时间:2019-03-29 09:35:31

标签: shell ksh

我有点挣扎。 在编写ksh脚本时,我需要提取String的Substring,其中dilimiter的出现次数是灵活的。

这是因为我的String拥有一个文件的名称,该文件可能会被压缩多次,因此其点数(。)多于1。 这些是我的定界符,但是由于供应商可能在文件名中包含版本号(例如,software-v.3.2.4.tar.gz),因此我发现没有要删掉最后一个后缀了。

进度如下:

文件名保存在变量中。 第一次解压缩文件。 (将.gz后缀从文件中删除) 现在,我需要提取.tar存档。但是我的命令仍将保留.gz后缀。由于该文件的后缀不再存在,因此命令将不起作用。

如何获取变量的后缀。 我不能保证定界符的数量保持不变。

我尝试了|的几种组合转速|凝乳'。' |转,但在这种情况下,我只能得到后缀。

我也尝试用文件的实际名称再次初始化$ fileName变量,但是因此我需要搜索整个目录。我尽量避免这种情况。

...

fileName="whole file name"
pathTo="path in which it should be moved after decompression"

if [ "$fileType" = "gz" ]; then

    gzip $pathTo$fileName -d $pathTo

    #Problem occurs right here

    tar xfv $pathTo$fileName -C $pathTo

else 
    echo "Unknown Filetype. Cannot decompress. Script stopped."
    exit

fi

...

感谢您的帮助。 问候

扬克

2 个答案:

答案 0 :(得分:0)

不要使用| rev | cut -d'.' -f 1 | rev而是使用| rev | cut -d'.' -f 2- | rev

答案 1 :(得分:0)

可变替换是此处的最佳选择,因为它是内置的外壳,也是最快的。

filename='software-v.3.2.4.tar.gz'
echo ${filename##*.}

输出将为gz

这不会修改变量$ filename的值。

if [[ "${filename##*.}" == "gz" ]]; then

工作方式

${var#pattern}-从左侧删除与模式匹配的文本后,使用var的值

${var##pattern}-与上面相同,但是删除了最长的匹配项,而不是最短的

${var%pattern}-从右侧删除与模式匹配的文本后,使用var的值

${var%%pattern}-与上面相同,但是删除了最长的匹配项,而不是最短的

还有更多,但这是相关的。

它们不能嵌套的局限性。