14

下手なバッシュの質問で申し訳ありませんが、解決できないようです。

次の簡単なケースがあります。

  • 私は次のような変数を持っていますartifact-1.2.3.zip

  • ハイフンとドットの最後のインデックスの間の部分文字列を取得したいと思います (どちらも排他的)。

私のバッシュスキルはあまり強くありません。私は次のものを持っています:

a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}

生産:

1.2.3.zip

.zipまた、その部分を削除するにはどうすればよいですか?

4

4 に答える 4

32

「変数置換」というタイトルのbashマニュアル ページ セクションでは、、、、および の使用について説明しています。${var#pattern}${var##pattern}${var%pattern}${var%%pattern}

と呼ばれる変数があると仮定するとfilename、たとえば、

filename="artifact-1.2.3.zip"

次に、パターンベースの抽出を次に示します。

% echo "${filename%-*}"
artifact

% echo "${filename##*-}"
1.2.3.zip

なぜ##代わりに使用したの#ですか?

ファイル名に次のようなダッシュが含まれている可能性がある場合:

filename="multiple-part-name-1.2.3.zip"

次に、次の 2 つの置換を比較します。

% echo "${filename#*-}"
part-name-1.2.3.zip

% echo "${filename##*-}"
1.2.3.zip

バージョンと拡張子を抽出したら、バージョンを分離するには、次を使用します。

% verext="${filename##*-}"
% ver="${verext%.*}"
% ext="${verext##*.}"
% echo $ver
1.2.3
% echo $ext
zip
于 2013-04-22T18:21:31.343 に答える
16
$ a="artifact-1.2.3.zip"; a="${a#*-}"; echo "${a%.*}"

'<code># pattern ' は、 patternが の先頭に一致する限り削除し$aます。patternの構文は、ファイル名の一致で使用されるものと似ています。私たちの場合には、

  • *任意の文字列です。
  • -文字通りのダッシュを意味します。
  • したがって、最初のダッシュ#*-を含むすべてに一致します。
  • したがって、 は、 が展開から取り除かれ、 が残ることを除いて、展開さ${a#*-}れるものすべてに展開されます。$aartifact-1.2.3.zip

同様に、'<code>% pattern ' は、展開の最後に一致する限り、パターンを削除します。私たちの場合には、

  • .文字通りのドット。
  • *任意の文字列。
  • したがって、最後のドット%.*を含む文字列の最後までのすべてです。
  • したがって、 がに$a展開される場合1.2.3.zip、 は に${a%.*}展開され1.2.3ます。

ジョブ完了。

このマニュアルページの内容は次のとおりです (少なくとも私のマシン YMMV では):

       ${パラメータ#単語}
       ${パラメータ##単語}
              単語は、パス名と同様にパターンを生成するために展開されます
              拡張。パターンが値の先頭に一致する場合
              パラメータの場合、展開の結果は展開された
              一致するパターンが最も短いパラメータの値 (「#」
              ケース) または最長一致パターン (``##'' ケース) が削除されます。
              パラメータが @ または * の場合、パターン除去操作が適用されます
              順番に各位置パラメーターに展開され、展開は
              結果リスト。パラメータが添字付きの配列変数の場合
              @ または * を使用すると、パターンの削除操作がそれぞれに適用されます。
              配列のメンバーを順番に展開し、展開はその結果です
              リスト。

       ${parameter%word}
       ${パラメータ%%単語}
              単語は、パス名と同様にパターンを生成するために展開されます
              拡張。パターンが
              パラメータの展開された値、展開の結果は
              一致するパターンが最も短いパラメーターの展開された値
              tern (``%'' ケース) または最長一致パターン (
              ``%%'' ケース) が削除されました。パラメータが @ または * の場合、パターン
              の各位置パラメータに削除操作が適用されます
              回転し、展開は結果のリストです。パラメータが
              @ または * で添字付けされた配列変数、パターンの削除
              操作は配列の各メンバーに順番に適用され、
              展開は結果のリストです。

チッ!

編集

詳細な回答については、@ x4dに感謝します。それでも人々は RTFM をすべきだと思っています。マニュアルを理解していない場合は、別の質問を投稿してください。

于 2013-04-22T17:51:54.957 に答える
3

Bash RegEx 機能の使用:

>str="artifact-1.2.3.zip"
[[ "$str" =~ -(.*)\.[^.]*$ ]] && echo ${BASH_REMATCH[1]}
于 2013-04-22T17:58:24.903 に答える
0

私はあなたがこれを行うことができると思います:

string=${a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}}

substring=${string:0:4}

最後の手順では、文字列から最後の 4 文字を削除します。ここにいくつかの詳細情報があります

于 2013-04-22T17:53:31.593 に答える