バッシュを使って

バッシュを使って

いくつかの調査を行った結果、文字列を「.」に分割できますが、置き換えたいのは3番目の「.」で、バージョン番号は実際には可変であるため、置き換え/分割をどのように実行しますか?

version: 1.8.0.110

しかし、私が望むものは次のように出力されます。

version: 1.8.0-110

答え1

たとえば、次のようになりますsed

$ echo 'version: 1.8.0.110' | sed 's/\./-/3'
version: 1.8.0-110

説明する:

sed s/search/replace/x文字列を検索して別の文字列に置き換えます。x交換するイベントを識別します。 3番目のイベントは次のとおりです。一般的に発生するすべての状況を指すためgに使用されます。x

ここでは点を置き換えようとしますが、これは正規表現の用語に必要な特殊文字です.。したがって、リテラルを指定するためにバックスラッシュを使用します。sedsearch.\..

パラメータに特殊文字sed(ここではバックスラッシュ)を使用しているため、パラメータ\全体を一重引用符で囲む必要があります''。多くの人は、スペースなどのシェル固有の文字を使用する問題を避けるために、常にここで引用符を使用しています。

答え2

バッシュを使って

特に交換したいと思うので、これを行うために外部プログラムは必要ありません。最後ダッシュのあるピリオドです。 Bashはデフォルトで文字列操作を処理できます。

あなたが持っていると仮定

vers='version: 1.8.0.110'

答えは簡単です。

$ echo ${vers%.*}-${vers##*.}
1.8.0-110

% は右から一致する最短文字列を削除することを意味します。 ##は、左から一致する最も長い文字列を削除することを意味します。

3サイクルを超えるとどうなりますか?

上記のように、最後の期間の代わりに3番目の期間を実際に置き換えたい場合、Bashでは少し難しいですが、それでも可能です。たとえば、vers='version: 1.8.0.110.hut.hut.hut.hike!'3番目のピリオド以降のすべての項目を見つけ、それを使用して文字列を切り捨てることができます。

$ end=${vers#*.*.*.}
$ start=${vers%$end}
$ echo ${start%.}-$end
version: 1.8.0-110.hut.hut.hut.hike!

他の方法:IFSを使用して文字列をbash配列に分割する

この問題については多少過度の作業ですが、時には文字列をコンポーネントに分割して配列にロードするのが便利な場合があります。

IFS=. read -a foo <<<'version: 1.8.0.110.hut.hut.hut.hike!'

配列を繰り返して$fooコンテンツを印刷するタイミングを選択できます。例えば、

echo -n $foo
for ((i=1; i<${foo[@]}; i++)); do 
  [[ i -eq 3 ]] && echo -n - || echo -n .
  echo -n ${foo[i]};
done
echo

答え3

この場合、3番目で最後です。常に最後の項目を変更する必要があると安全に想定できる場合は、.次のようにできます。

$ echo 'version: 1.8.0.110' | sed 's/\.\([^.]*\)$/-\1/'
version: 1.8.0-110

またはあなたがsed支持する場合-E(ほとんどそうする):

$ echo 'version: 1.8.0.110' | sed -E 's/\.([^.]*)$/-\1/'
version: 1.8.0-110

行末()までを検索し、.ゼロ個以上の文字以外の.文字()を探します。括弧()で囲まれているため、「キャプチャ」され、置換演算子の右側で参照できます。したがって、次の文字と非文字はaとその文字に置き換えられます。[^.]$[^.]*\( \)\1.-.-


今回が最後ではなく3回目でなければならない場合@Ned64が最も簡単な方法を提示しました。しかし、代わりに、次のことができます。

$ echo 'version: 1.8.0.110' | perl -pe 's/(([^.]+\.){2}[^.]+)\./$1-/'
version: 1.8.0-110

関連情報