改行文字を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
(新しい行がデフォルト値なので、$IFS
NULで区切られたレコードを読み取りても空の結果が出る理由を説明します)。これを使用して、読み取るレコードの長さを制限できます。
あなたの場合、NULで区切られたレコード(使用-d ''
)を使用すると、変数にNUL文字を格納できないのと同じように機能するため、空のままでIFS= read -d '' -rn1 var
ゼロ以外の終了状態を返します。bash
printf '\0' | read -rN1 var
$var
NUL を含む任意の文字を読み取るには、zsh
次の構文を代わりに使用してシェルを使用できます。
read -k1 'var?Enter a character: '
(必要ありません-r
。IFS=
でも必ずread -k
お読みください。ターミナルから(k
鍵; zsh オプションは-k
bash や 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では、スペース、タブ、および改行を区別することはできません。