1. ホーム
  2. bash

[解決済み] Bashで文字列をデリミターで分割するには?

2022-03-17 22:03:18

質問

この文字列を変数に格納しています。

IN="[email protected];[email protected]"

で文字列を分割したいと思います。 ; というようにデリミタがあります。

ADDR1="[email protected]"
ADDR2="[email protected]"

は必ずしも必要ではありません。 ADDR1ADDR2 という変数があります。それらが配列の要素であれば、なおさらです。


以下の回答からの提案の後、結局私が求めていたのは以下のようなものでした。

#!/usr/bin/env bash

IN="[email protected];[email protected]"

mails=$(echo $IN | tr ";" "\n")

for addr in $mails
do
    echo "> [$addr]"
done

出力します。

> [[email protected]]
> [[email protected]]

を設定することで、解決することができました。 インターナルフィールドセパレータ (IFS) を ; . その回答で何が起こったのかよくわからないのですが、どのようにリセットするのでしょうか? IFS をデフォルトに戻しますか?

RE: IFS の解決策として、私はこれを試してみたところ、うまくいきました。 IFS を作成し、それを復元する。

IN="[email protected];[email protected]"

OIFS=$IFS
IFS=';'
mails2=$IN
for x in $mails2
do
    echo "> [$x]"
done

IFS=$OIFS

ちなみに、私が試したときは

mails2=($IN)

を括弧で囲まないでループで印刷すると、最初の文字列だけが表示されました。 $IN が動作します。

解決方法は?

を設定することができます。 内部フィールドセパレータ (IFS)変数に格納し、配列にパースさせます。このようなことがコマンドの中で起こると、その代入先が IFS は、その単一のコマンドの環境に対してのみ行われます (そのコマンドの read ). そして、入力を IFS を配列に変換し、それを反復処理することができます。

この例では、1行の項目を ; それを配列に格納します。

IFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
  # process "$i"
done

のコンテンツ全体を処理する例です。 $IN で区切られた1行の入力に対して、その都度 ; :

while IFS=';' read -ra ADDR; do
  for i in "${ADDR[@]}"; do
    # process "$i"
  done
done <<< "$IN"