Anda perlu menghapus karakter spasi dari $IFS
parameter untuk read
berhenti melompati karakter yang memimpin dan mengekor (dengan -n1
, karakter spasi jika ada yang akan memimpin dan mengekor, jadi dilewati):
while IFS= read -rn1 a; do printf %s "$a"; done
Tetapi meskipun demikian, bash's read
akan melewati karakter baris baru, yang dapat Anda atasi:
while IFS= read -rn1 a; do printf %s "${a:-$'\n'}"; done
Meskipun Anda dapat menggunakan IFS= read -d '' -rn1
sebagai gantinya atau bahkan lebih baik IFS= read -N1
(ditambahkan pada 4.1, disalin dari ksh93
(ditambahkan dalam o
)) yang merupakan perintah untuk membaca satu karakter.
Perhatikan bahwa bash read
tidak dapat mengatasi karakter NUL. Dan ksh93 memiliki masalah yang sama dengan bash.
Dengan zsh:
while read -ku0 a; do print -rn -- "$a"; done
(zsh dapat mengatasi karakter NUL).
Perhatikan bahwa mereka read -k/n/N
membaca sejumlah karakter , bukan byte . Jadi untuk karakter multibyte, mereka mungkin harus membaca beberapa byte hingga karakter penuh dibaca. Jika input berisi karakter yang tidak valid, Anda mungkin berakhir dengan variabel yang berisi urutan byte yang tidak membentuk karakter yang valid dan yang shell akhirnya menghitung sebagai beberapa karakter . Misalnya di lokal UTF-8:
$ printf '\375\200\200\200\200ABC' | bash -c '
IFS= read -rN1 a; echo "${#a}"'
6
Itu \375
akan memperkenalkan karakter UTF-8 6-byte. Namun, yang ke-6 ( A
) di atas tidak valid untuk karakter UTF-8. Anda masih berakhir dengan \375\200\200\200\200A
di $a
, yang bash
dihitung sebagai 6 karakter meskipun 5 yang pertama tidak benar-benar karakter, hanya 5 byte yang tidak membentuk bagian dari karakter apa pun.
IFS
apa-apa agar spasi putih bertahan dari pemisahan kata.