`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