18

私はシェルプログラミングに不慣れです。zipファイルを解凍した後にディレクトリ名を取得するつもりです。それの印刷ステートメントは

$test.sh helloworld.zip
helloworld

test.shを見てみましょう:

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

しかし、コンパイラから不正な置換エラーが発生しました。

そして、「シェル」について言及するとき、私はシェルについて話しているだけです。bashと他の人の違いがわかりません。Ubuntu10.04とターミナルを使用しています。(私はbashを使用しています。)

4

3 に答える 3

17

シェルがの十分に新しいバージョンであるbash場合、そのパラメーター展開表記は機能するはずです。

他の多くのシェルでは、それは機能しません。bad substitutionエラーは、シェルが「パラメーターの置換を要求しましたが、私には意味がありません」と言う方法です。


また、スクリプトが与えられた場合:

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

2行目は、を実行して生成されたコマンドのlength値を持つ変数をエクスポートします。には割り当てられません。それはちょうどあるべきです:echoexpr index "$1" .ziplength

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

ここで、が設定されていない場合(スクリプトが引数なしで呼び出された場合) 、${1:?}表記はエラーを生成します。$1

最後の行は次のようになります。

echo ${a:0:$length}

$1が成立する場合、文字はのインデックス2に表示されるためfilename.zip、の出力は2であることに注意してください。拡張子なしでファイルのベース名を取得することが目的の場合、それを行うための古典的な方法は次のとおりです。expr index $1 .zipifilename.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)`.)

ファイル名にスペースを含めることができる場合は、特にとの呼び出しで二重引用符を使用することを検討する必要がありbasenameますdirname

于 2012-10-11T03:50:13.690 に答える
8

bashで実行してみてください。

bash test.sh helloworld.zip

-同じく-

コメントとして「最初の行を#!/ bin / bashに変更してみてください」– @shellter

于 2018-10-03T15:42:16.493 に答える
1

でそれを試してみてくださいbash

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

ニーズに合わせて調整してください。

于 2012-10-11T03:53:09.663 に答える