直接の答え

直接の答え

Bashでは、トークン化はコマンドライン処理の1つのステップです。 Bashマニュアルから

シェルは$ IFSの各文字を区切り文字として扱い、これらの文字をフィールドの終端として使用して、他の拡張結果を単語に分割します。 IFSが設定されていない<space><tab><newline>場合、またはその値がデフォルト値の場合、前の <space>, <tab>, and <newline>拡張結果の始まりと終わりのシーケンスは無視され、始まりまたは終わりにないIFS文字シーケンスは単語を区切るために使用されます。 IFSにデフォルト以外の値がある場合、スペース文字がIFS値(IFSスペース)にある限り、単語の先頭と末尾のスペースとタブのシーケンスは無視されます。 IFS スペースではなく、IFS のすべての文字と隣接する IFS スペース文字が一緒にフィールドを区別します。空白文字の IFS シーケンスも区切り文字と見なされます。 IFS値が空の場合、単語分割は発生しません。

spaceパラメータ間の区切り文字がまたはで置き換えられるように、次の例を書き直したいと思いますabctabnewline

$ echo a b c
a b c

しかし、ボタンを押してもTab何も起こりません。

をクリックすると、\出力に、との間にスペースがありませんreturnabc

$ echo a\
> b\
> c
abc

なぜ引用文で言うようにできないのですか?

しかし、何の結果も出ません$IFS

$ echo $IFS

答え1

bash改行文字は値に関係なく特別に処理されますIFS。改行前のバックスラッシュにより改行が発生します。無視される。これは、単語の分割に関係なく、IFS一部のカスタム値に設定されている場合にも発生します。

からLESS=+/^QUOTING man bash

   A  non-quoted  backslash (\) is the escape character.  It preserves the
   literal value of the next character that follows, with the exception of
   <newline>.   If  a  \<newline>  pair  appears, and the backslash is not
   itself quoted, the \<newline> is treated as a line  continuation  (that
   is, it is removed from the input stream and effectively ignored).

改行文字で単語分割が異なる方法で発生することがわかります。つまり、改行文字を変数に入れてから、引用しないでecho変数を参照します。

$ myvar=a$'\n'b$'\n'c
$ echo "$myvar"
a
b
c
$ echo $myvar
a b c
$ 

答え2

直接の答え

これ引用しないコマンド: 、それが何であれecho a b c(メタ文字スペース)に分割されます。 :echoは次のように定義されているため、分割パラメータはスペースで印刷されます。IFSechoabc

LESS=+/'^ *echo \[-neE\] \[arg ...\]' man bash

スペースで区切られた出力パラメーターとそれに続く改行文字が続きます。

参加もありません$IFS

したがって、あなたが引用した内容はここでは関係ありません。主な部分は次のとおりです。

...異なる拡張の結果を単語に分割...

あなた〜しなければならない$IFS使用前の延長があります。
には拡張子がありませんa b c

$IFSの効果を使用する必要がある場合は、引用符なしの拡張機能を使用してください。

$ var='a   b   c'
$ echo $var
a b c

ただし、これはまだ$IFS出力には使用されず、分割にのみ使用されます。

出力のIFS。

$IFSの相関関係(出力について)はどこにありますか$*

$ set -- a b c
$ IFS=$'\t'
$ printf '%s\n' "$*" | od -An -vtx1c
  61  09  62  09  63  0a
   a  \t   b  \t   c  \n

これはあなたに必要なものですか?


その他の事項

キーボードタブ

Tabキーを押しても何も起こりません

次に、を押してCtrlV手を離し、同時にを押しますTab

ただし、引用符がないと、変数にタブ文字を割り当てることはできません。テスト:

$ var=a    b                  ### The space represents a tab as above.
bash: b: command not found

必要になります。

$ var="a   b"                 ### The space represents a tab as above.

少なくとも二重引用符です。

見積もりIFS

$ IFSの結果はありません。

$ echo $IFS

$IFS参照がないため、何も生成されません$IFS。努力する:

<user>$ echo "$IFS" | sed -n l
 \t$
$
<user>$

$IFSechoコマンドの新しい行とechoコマンドの新しい行があります。
printfに変更することをお勧めします。

<user>$ printf '%s' "$IFS" | sed -n l
 \t$
<user>$

そしてodを使う:

$ printf '%s' "$IFS" | od -An -vtx1c
  20  09  0a
      \t  \n

文字列にどの文字が含まれているかを「確認」する方法が既にあるためです。
また、これを使用して複数の文字列内の内容を「表示」することもできます。

$ var='a b c'
$ echo "$var" | od -An -vtx1c
  61  20  62  20  63  0a
   a       b       c  \n

これは驚くべきことではありません。なぜなら、これは(一重引用符で)次のようにしてはいけません。

$ var='a\
> b\
> c'
$ echo "$var" | od -An -vtx1c
  61  5c  0a  62  5c  0a  63  0a
   a   \  \n   b   \  \n   c  \n

正確に入力された内容です。 varが正しく引用されると、バックスラッシュが正しく表示されます。

引用する

ただし、二重引用符で引用すると、一部の文字が変更されることがあります。

$ var="a\
> b\
> c"
$ echo "$var" | od -An -vtx1c
  61  62  63  0a
   a   b   c  \n

しかし、あなたが書いた内容には、var設定やエコーで使用することに関する引用はありません。
これはシェルにとってはいけないことです。お願いします正しい引用

答え3

スペースをタブに置き換えるには、$IFSパラメータ配列を使用できます。

unset IFS
set a b c
IFS=$(printf \\t)
printf "%s\n" "$*"

これが$IFS分割に関連していることを理解してください。これには、リストのコンテキストを分割するためにシェルが使用する引用符のない拡張文字のリストが含まれています。君はそれを本当に使えないじゃない変える特殊シェルパラメータの特別な場合を除く文字です$*。他のすべてのケースでは、その使用は次のとおりです。無効引用符で囲まれていないシェル拡張の特定の部分を明確にして区別します。

関連情報