76

IFS を次のように改行で分割するように設定するときに、バックスペースが必要な理由について知りたいです。

IFS=$(echo -en "\n\b")

代わりにこれを使用できないのはなぜですか (これは機能しません)。

IFS=$(echo -en "\n")

Unix の行末でファイルを保存している Linux システムを使用しています。改行を含むファイルを16進数に変換しましたが、改行文字として「0a」のみを使用していることは間違いありません。

多くのページで改行とそれに続くバックスペースのソリューションが文書化されていますが、バックスペースが必要な理由を説明しているページはありません。

-デビッド。

4

5 に答える 5

140

コマンド置換に関してbashマニュアルが述べているように:

Bash は、コマンドを実行し、コマンド置換をコマンドの標準出力に置き換え、末尾の改行を削除することによって展開を実行します。

したがって、追加\bすることで、の削除を防ぐことができます\n

これを行うためのよりクリーンな方法は$''、次のように引用を使用することです。

IFS=$'\n'
于 2013-05-30T08:51:17.283 に答える
12

echoコマンド置換を使用しているため、これはハックです。

prompt> x=$(echo -en "\n")
prompt> echo ${#x}
0
prompt> x=$(echo -en "\n\b")
prompt> echo ${#x}
2

$()末尾の改行を削除し、末尾の改行になるのを\b防ぎ\nますが、テキストに表示される可能性はほとんどありません。IFS=$'\n'改行で分割するように IFS を設定するより良い方法です。

于 2013-05-30T09:07:26.703 に答える
5

コマンド置換で末尾が削除されたため、改行のサフィックスとして char が追加されまし\bた。そのため、は の接尾辞として使用され、byはもはや末尾にないため、コマンド置換から返されます。\n\n$(...)\b\n\n

副次的効果は、char だけでなく、セパレーターとしてもIFS含まれることです。これは、私たちの唯一の関心事です。\b\n

いつか文字列に表示されると予想さ\bれる場合 (なぜ表示されないのですか?)、次のように使用できます。

IFS="$(printf '\nx')" && IFS="${IFS%x}";

それreturns \n suffixed with x && removes x

現在、IFS には\nchar のみが含まれています。

IFS="$(printf '\nx')" && IFS="${IFS%x}";
echo ${#IFS}; # 1

\b、テストの場合、何も壊れません:

#!/bin/sh

sentence=$(printf "Foo\nBar\tBaz Maz\bTaz");
IFS="$(printf '\nx')" && IFS="${IFS%x}";

for entry in $sentence
do
    printf "Entry: ${entry}.\n";
done

2行を提供します(1つのため\n):

Entry: Foo.
Entry: Bar      Baz Maz Taz.

予想通り。

IFS="$(printf '\nx')" && IFS="${IFS%x}";使用:

IFS="
"

同じ結果が得られますが、これらの 2 行をインデントしてはなりません。" と " の間に誤ってスペースやタブ、またはその他の白い文字を入れた場合、\nそこにある文字だけではなく、いくつかの "ボーナス" も含まれます。 . エディタで「すべての文字を表示」オプションを使用しない限り、このバグを見つけるのは困難です。

于 2020-06-27T04:43:20.243 に答える