2012-10-11 104 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} 

適應它來滿足您的需求。