2012-10-11 106 views
4

我知道这是愚蠢的,但我在外壳新,我真的不知道发生了什么事情here.Following是打算用于获取目录名称的压缩文件后,extract.Thus,如果工作,结果将像这样shell字符串替换坏

$test.sh helloworld.zip 
helloworld 

让我们来看看test.sh:

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

但是我得到了坏替代和刚刚陷入困境。
当我提到关于“shell'.I只是在谈论壳,因为我不知道刚才使用Ubuntu 10.04的bash或others.I之间的differnce并使用我想我使用bash的terminal.And。

+0

你想做什么? –

+0

您对剧本的理由是什么,即$ 1的价值?请将上述信息编辑成上述信息,而不是回复我的评论。尝试在dbl引号中包含所有对$ 1的引用,即'echo“$ 1”'等等,祝你好运! – shellter

+0

你用'$ {a:0}'发现了什么? –

回答

3

如果你的shell是足够新的版本bash,即parameter expansion符号应该工作。

在其他许多炮弹,它不会工作,并且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.zipexpr index $1 .zip输出为2,因为字母i在指数2 filename.zip出现。如果目的是获取文件的基本名称,而不.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

什么是“最新版本”?我正在使用bash 4.2.37,我正面临着这个问题。 – Simon

+0

@Simon:它适用于Bash 3.2.51(随Mac OS X 10.9.2 Mavericks提供)。它也适用于Bash 4.2.25(随Ubuntu 12.04提供)。例如:'AZ = abcdefghijklmnopqrstuvwxyz; echo $ {AZ:10:10}'在两个系统上产生'klmnopqrst'。此外,无论它是Bash作为'bash'还是'sh'运行都可以。所以,你需要详细说明你在做什么,按照我刚才给出的例子。请注意,这两个值都必须是数字。你可以这样写:'length = 10'和'echo $ {AZ:10:$ length}',但第二个'$'在这个表示法中至关重要。 –

+0

感谢您的快速回答。其实'AZ = abcdefghijklmnopqrstuvwxyz; echo $ {AZ:10:10}'对我来说会产生一个坏取代(Bash 4.2.37 - Debian 7.4)。我想我必须深入挖掘。 – Simon

0

尝试在bash

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

适应它来满足您的需求。