bash:読み取り:「\ n」(改行)文字をキャプチャする方法は?

bash:読み取り:「\ n」(改行)文字をキャプチャする方法は?

改行文字をreadキャプチャまたは切断するために使用できるものはありますか?\n \012

テスト機能を定義します。

f() { read -rd '' -n1 -p "Enter a character: " char &&
      printf "\nYou entered: %q\n" "$char"; }

この機能を実行するには、[次へ]を押しますEnter

$ f;
Enter a character: 

You entered: ''

まあ。これは空の文字列です。

予想される出力を取得するにはどうすればよいですか?

$ f;
Enter a character:

You entered: $'\012'
$ 

^Dまたは\004

できない場合、read解決策は何ですか?

答え1

1つの文字を読み取るには、-N常に1つの文字を読み取って$IFS処理を行わないでください。

read -rN1 var

read -rn1最大1文字までレコードを読み取り、処理を続行します$IFS(新しい行がデフォルト値なので、$IFSNULで区切られたレコードを読み取りても空の結果が出る理由を説明します)。これを使用して、読み取るレコードの長さを制限できます。

あなたの場合、NULで区切られたレコード(使用-d '')を使用すると、変数にNUL文字を格納できないのと同じように機能するため、空のままでIFS= read -d '' -rn1 varゼロ以外の終了状態を返します。bashprintf '\0' | read -rN1 var$var

NUL を含む任意の文字を読み取るには、zsh次の構文を代わりに使用してシェルを使用できます。

read -k1 'var?Enter a character: '

(必要ありません-rIFS=でも必ずread -kお読みください。ターミナルからk; zsh オプションは-kbash や ksh93 よりも-N数十年長くなりました。標準入力から読むにはread -u0 -k1)を使用してください。

はい(Ctrl+SpaceここでNUL文字を入力してください):

$ read -k1 'var?Enter a character: '
Enter a character: ^@
$ printf '%q\n' $var
$'\0'

読めるので参考にしてください特徴read複数のバイトを読み取る必要があるかもしれません。入力がマルチバイト文字の最初のバイトで始まる場合、少なくとも1バイトがさらに読み取られます。したがって、$var入力に有効なシーケンスを形成しないバイトシーケンスが含まれている場合、シェルが考慮する内容を含めることができます。 1文字より長くなければなりません。

たとえば、UTF-8ロケールでは次のようになります。

$ printf '\xfc\x80\x80\x80\x80XYZ' | bash -c 'read -rN1 a; printf "<%q>\n" "$a" "${#a}"; wc -c'
<$'\374\200\200\200\200X'>
<6>
2
$ printf '\xfc\x80\x80\x80\x80XYZ' | zsh -c 'read -u0 -k1 a; printf "<%q>\n" $a $#a; wc -c'
<$'\374'$'\200'$'\200'$'\200'$'\200'X>
<6>
2

UTF-8では、0xFCは6バイトの長い文字の最初のバイトであり、残りの5バイトはビット8が設定され、ビット7が設定されていないことを意味しますが、4つだけを提供しました。文字の終わりを見つけるためにread追加情報を読み続けると、有効な文字を形成しない5バイトになり、各バイトは最終的に1文字としてカウントされます。X$var

答え2

bash組み込み機能はread次のことができます。

read -rd $'\0' -p ... -n 1
printf '\nYou typed ASCII %02x\n' "'$REPLY"

(このコードはマルチバイト文字では機能しません。)

私はあなたのように私が読んだ内容を変数に入れなかったことに注意してくださいchar。これは、IFSから文字を削除するためですchar。標準IFSでは、スペース、タブ、および改行を区別することはできません。

関連情報