`read`と` IFS`が空白文字をマージしないようにするにはどうすればよいですか?[複製]

Nov 26 2020

で区切られたデータを読み込むこのコードを使用してください |

DATA1="Andreas|Sweden|27"
DATA2="JohnDoe||30"   # <---- UNKNOWN COUNTRY
while IFS="|" read -r NAME COUNTRY AGE; do 
    echo "NAME:    $NAME"; echo "COUNTRY: $COUNTRY";
    echo "AGE:     $AGE"; done<<<"$DATA2"

出力:

名前:JohnDoe国

年齢:30

これは、まったく同じことを実行しているこのコードと同じように機能するはずです\t、代わりにセパレータとして使用するだけです。|

DATA1="Andreas  Sweden  27"
DATA2="JohnDoe      30"  # <---- THERE ARE TWO TABS HERE
while IFS=$'\t' read -r NAME COUNTRY AGE; do echo "NAME: $NAME";
    echo "COUNTRY: $COUNTRY"; echo "AGE: $AGE";
done<<<"$DATA2"

しかし、そうではありません。

出力:

名前:JohnDoe国
:30
年齢:

Bash、またはreadまたはIFSコードの他の部分が、想定外の空白をグロブしている。なぜこれが起こっているのですか、どうすれば修正できますか?

回答

3 fpmurphy Nov 26 2020 at 11:00

bash正常に動作しています。bashドキュメントから:

シェルはIFSの各文字を区切り文字として扱い、他の展開の結果をこれらの文字の単語に分割します。IFSが設定されていない、またはその値が正確であれば<space><tab><newline>、その後、デフォルトのシーケンス<space><tab>および<newline>前の展開の結果の最初と最後は無視され、最初または最後にないIFS文字のシーケンスは単語を区切るのに役立ちます。IFSの値がデフォルト以外の場合、空白文字がIFS(IFS空白文字)の値に含まれている限り、単語の最初と最後で空白文字のスペースとタブのシーケンスは無視されます。IFS空白以外のIFS内の文字は、隣接するIFS空白文字とともに、フィールドを区切ります。IFS空白文字のシーケンスも区切り文字として扱われます。

この「機能」を克服するには、次のようなことを行うことができます。

#!/bin/bash

DATA1="Andreas  Sweden  27"
DATA2="JohnDoe          30"  # <---- THERE ARE TWO TABS HERE

echo "$DATA2" | sed 's/\t/;/g' | while IFS=';' read -r NAME COUNTRY AGE; do echo "NAME: $NAME"
    echo "COUNTRY: $COUNTRY" echo "AGE: $AGE"
done