shell字符串坏替换

时间:2012-10-11 03:36:24

标签: string shell substitution

我知道这很愚蠢,但我是shell的新手,我真的不知道这里发生了什么。以下是打算在zip文件被提取后获取目录名。因此,如果有效,结果将是这样的< / p>

$test.sh helloworld.zip
helloworld

我们来看看test.sh:

#! /bin/sh
length=echo `expr index "$1" .zip`
a=$1    
echo $(a:0:length}

然而,我得到了糟糕的替代,而这只是搞砸了 当我提到'shell'时。我只是在谈论shell,因为我不知道bash或其他人之间的差异。我只是使用ubuntu 10.04并使用终端。我想我正在使用bash。

3 个答案:

答案 0 :(得分:4)

如果您的shell是bash的最新版本,则parameter expansion符号应该有效。

在许多其他shell中,它不起作用,并且bad substitution错误就是shell说“你要求参数替换,但它对我没有意义”的方式。


另外,给出了脚本:

#! /bin/sh
length=echo `expr index "$1" .zip`
a=$1    
echo $(a:0:length}

第二行导出变量length,其值为echo,用于运行expr index "$1" .zip生成的命令。它不会分配给length。那应该只是:

length=$(expr index "${1:?}" .zip)

如果未设置${1:?},则$1表示法会生成错误(如果没有参数调用脚本)。

最后一行应该是:

echo ${a:0:$length}

请注意,如果$1保留filename.zip,则expr index $1 .zip的输出为2,因为i中的字母filename.zip出现在索引2处。如果目的是获取没有.zip扩展名的文件的基本名称,那么经典的方法是:

base=$(basename $1 .zip)

更现代的方式是:

base=${1%.zip}

有区别;如果名称为/path/to/filename.zip,则经典输出为filename,现代输出为/path/to/filename。您可以通过以下方式获得经典输出:

base=${1%.zip}
base=${base##*/}

或者,在经典版本中,您可以通过以下方式获取路径:

base=$(dirname $1)/$(basename $1 .zip)`.)

如果文件名可以包含空格,则需要考虑使用双引号,尤其是在basenamedirname的调用中。

答案 1 :(得分:2)

尝试使用bash运行它。

bash test.sh helloworld.zip

-likewise-

“尝试将第一行更改为#!/ bin / bash ”,方法是– @shellter

答案 2 :(得分:0)

bash中尝试:

echo $1
len=$(wc -c <<< "$1")
a="${1}.zip"
echo ${a:0:$len}

根据您的需要调整它。