shell 字符串替换错误

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

我是 shell 编程新手。我打算在提取 zip 文件后获取目录名称。它的打印语句是

$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。)

string shell substitution
3个回答
19
投票

如果您的 shell 是

bash
的最新版本,则 参数扩展 表示法应该有效。

在许多其他 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)

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

basename
dirname
时。


9
投票

尝试使用 bash 运行它。

bash test.sh helloworld.zip

-同样-

“尝试将第一行更改为 #!/bin/bash”作为评论回答 – @shellter


1
投票

尝试一下

bash
:

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

调整它以满足您的需求。

© www.soinside.com 2019 - 2024. All rights reserved.