GNU/Linux >> Linux の 問題 >  >> Linux

`while Ifs =Read ..`で、なぜIfsは効果がないのですか?

私は絶対に間違っているかもしれませんが、IFSをコマンドの1つとして設定することは私には説得力があるように見えます pre-do /doneリストにあるものはまったく効果がありません。
外部IFS(whileの外) コンストラクト)は、以下のスクリプトに示されているすべての例で優先されます。

何が起きてる?この状況でIFSが何をするかについて間違った考えを持っていますか?配列分割の結果は、「期待される」列に示されているとおりになると期待していました。

#!/bin/bash
xifs() { echo -n "$(echo -n "$IFS" | xxd -p)"; } # allow for null $IFS 
show() { x=($1) 
         echo -ne "  (${#x[@]})t |"
         for ((j=0;j<${#x[@]};j++)); do 
           echo -n "${x[j]}|"
         done
         echo -ne "t"
         xifs "$IFS"; echo
}
data="a  b   c"
echo -e "-----   --  -- t --------tactual"
echo -e "outside        t  IFS    tinside" 
echo -e "loop           t Field   tloop" 
echo -e "IFS     NR  NF t Split   tIFS (actual)" 
echo -e "-----   --  -- t --------t-----"
IFS=$' tn'; xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 1'; show "$REPLY"; done 
IFS=$' tn'; xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't 2'; show "$REPLY"; done 
IFS=$' tn'; xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 3'; show "$REPLY"; done
IFS=" ";      xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 4'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't 5'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 6'; show "$REPLY"; done
IFS=;         xifs "$IFS"; echo "$data" | while         read; do echo -ne 't 7'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne 't 8'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne 't 9'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne 't10'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne 't11'; show "$REPLY"; done
echo -e "-----   --  -- t --------t-----"

出力:

-----   --  --   --------       actual   
outside           IFS           inside                assigned   
loop             Field          loop    #              inner
IFS     NR  NF   Split          IFS     #  expected    IFS
-----   --  --   --------       -----   #  ---------  --------
20090a   1  (3)  |a|b|c|        20090a  #                              
20090a   2  (3)  |a|b|c|        20090a  #  |a  b   c|  IFS=
20090a   3  (3)  |a|b|c|        20090a  #  |a  |   c|  IFS=b
20       4  (3)  |a|b|c|        20      #                          
20       5  (3)  |a|b|c|        20      #  |a  b   c   IFS=
20       6  (3)  |a|b|c|        20      #  |a  |   c|  IFS=b
         7  (1)  |a  b   c|             #                          
         8  (1)  |a  b   c|             #  |a|b|c|     IFS=" "
         9  (1)  |a  b   c|             #  |a  |   c|  IFS=b
62      10  (2)  |a  |   c|     62      #  |a  b   c|  IFS=
62      11  (2)  |a  |   c|     62      #  |a|b|c|     IFS=" "
-----   --  --   --------       -----      ---------   -------                        

承認された回答:

(申し訳ありませんが、長い説明)

はい、IFS while IFS=" " read; do … 残りのコードには影響しません。

関連:PDF内の情報を読みますか?

まず、シェルコマンドラインが2種類の変数を備えていることを正確に説明しましょう。

  • シェル変数(シェル内にのみ存在し、シェルに対してローカルです)
  • すべてのプロセスに存在する環境変数。これらは通常、fork()で保持されます およびexec() 、したがって子プロセスはそれらを継承します。

次のコマンドを使用してコマンドを呼び出す場合:

  A=foo B=bar command

コマンドは、(環境)変数Aが存在する環境内で実行されます。 fooに設定されています およびB barに設定されています 。ただし、このコマンドラインでは、現在のシェル変数A およびB 変更されていない

これは次とは異なります:

A=foo; B=bar; command

ここで、シェル変数A およびB が定義され、コマンドが環境変数Aなしで実行されます およびB 定義されています。 Aの値 およびB commandからアクセスできません 。

ただし、一部のシェル変数がexportの場合 -edの場合、対応する環境変数はそれぞれのシェル変数と同期されます。例:

export A
export B
A=foo; B=bar; command

このコードでは、両方のシェル 変数とシェル環境 変数はfooに設定されます およびbar 。環境変数はサブプロセスに継承されるため、command それらの値にアクセスできるようになります。

元の質問に戻るには、次の場所にあります:

IFS='a' read

readのみ 影響を受けた。実際、この場合、read IFSの値は気にしません 変数。 IFSを使用します 次のように、行を分割する(そしていくつかの変数に格納する)ように要求した場合のみ:

echo "a :  b :    c" | IFS=":" read i j k; 
    printf "i is '%s', j is '%s', k is '%s'" "$i" "$j" "$k"

IFS readでは使用されません 引数で呼び出されない限り。 (編集: これは正確には当てはまりません。IFSに存在する空白文字、つまりスペースとタブ 入力行の最初/最後では常に無視されます。 )


Linux
  1. PrintfがEchoよりも優れているのはなぜですか?

  2. `ifs=の代わりに`whileIfs=Read`が頻繁に使用されるのはなぜですか。読みながら..`?

  3. Ifsを理解していますか?

  1. 新しいディレクトリに何かが追加される前に、ハードリンクカウントが2になるのはなぜですか?

  2. `md5sum`がインターネットと同じハッシュを与えないのはなぜですか?

  3. Linux – Ioniceは、同期されていない書き込み(つまり、通常の書き込み)に影響を与えませんか?

  1. Pythonにはargc引数がありますか?

  2. IFS を改行で分割するように設定する場合、バックスペースを含める必要があるのはなぜですか?

  3. Matrox GPU とは何ですか? また、大学の UNIX サーバーに Matrox GPU があるのはなぜですか?