211

私は解決策を探していて、同様の質問を見つけましたが、それらは文章をスペースで区切ろうとしているだけで、私の状況では答えがうまくいきません。

現在、変数は次のような文字列に設定されています。「 -
ABCDE-123456
」 を削除しながら、それを2つの変数に分割したいと思います。すなわち:
var1=ABCDE
var2=123456

どうすればこれを達成できますか?


これは私のために働いた解決策です:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

区切り文字なしで機能するカットコマンドを使用することは可能ですか (各文字は変数として設定されます)。

var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.

4

5 に答える 5

263

で区切られた文字列を分割するには、次のように-使用できます。readIFS

$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo "$var1"
ABCDE
$ echo "$var2"
123456

編集:

個々の文字を配列要素に読み込む方法は次のとおりです。

$ read -a foo <<<"$(echo "ABCDE-123456" | sed 's/./& /g')"

配列をダンプします。

$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]="-" [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'

文字列にスペースがある場合:

$ IFS=$'\v' read -a foo <<<"$(echo "ABCDE 123456" | sed 's/./&\v/g')"
$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]=" " [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'
于 2012-05-10T03:14:24.343 に答える
219

2 つのフィールドだけになることがわかっている場合は、次のように追加のサブプロセスをスキップできます。

var1=${STR%-*}
var2=${STR#*-}

これは何をしますか?文字列の末尾から開始して、パターンに一致する${STR%-*}の最も短い部分文字列を削除します。同じことを行いますが、パターンを使用し、文字列の先頭から開始します。それぞれに対応するものがあり、アンカーされたパターンの最長一致を見つけます。覚えておくと便利なニーモニックがあれば教えてください。覚えるには、常に両方を試してみる必要があります。$STR-*${STR#*-}*-%%##

詳細については、bash のドキュメントを参照してください。

于 2012-05-09T17:02:19.263 に答える
182

ソリューションが一般的である必要がない場合、つまり、例のような文字列に対してのみ機能する必要がある場合は、次のようにすることができます。

var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

ここを選択cutしたのは、いくつかの変数のコードを単純に拡張できるからです...

于 2012-05-09T17:00:36.877 に答える
49

setカスタムの仕事のように聞こえIFSます。

IFS=-
set $STR
var1=$1
var2=$2

(これを a を含む関数で実行することをお勧めします。これにより、スクリプトの他の部分で期待どおりになるlocal IFS必要がある場所を台無しにしないでください。)IFS

于 2012-05-09T17:57:58.760 に答える
33

bash正規表現機能の使用:

re="^([^-]+)-(.*)$"
[[ "ABCDE-123456" =~ $re ]] && var1="${BASH_REMATCH[1]}" && var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2

出力

ABCDE
123456
于 2012-05-09T17:09:48.793 に答える