bash – 读取-N和IFS
根据手册页中的“读-N”说明:
-N nchars仅在读取完全NCHARS字符后返回,除非遇到EOF或读取超时,忽略任何分隔符 但是,在回答以下命令时: $echo 'a b' | while read -N1 c; do echo ">>>$c<<<"; done >>>a<<< >>><<< >>>b<<< >>><<< 空格和换行符都已转换为空字符串,而在命令中: $echo 'a b' | while IFS= read -N1 c; do echo ">>>$c<<<"; done >>>a<<< >>> <<< >>>b<<< >>> <<< 空格和换行符已正确存储在变量中. 因此,似乎分隔符仍然在“读取”或“同时”命令中有一些处理,我不明白. 我们可以将这些结果与使用“read -n”的结果进行比较,该手册描述为: -n nchars在读取NCHARS字符后返回而不是等待换行符,但如果在分隔符之前读取的NCHARS字符少于NCHARS字符,则表示分隔符 $echo 'a b' | while read -n1 c; do echo ">>>$c<<<"; done >>>a<<< >>><<< >>>b<<< >>><<< $echo 'a b' | while IFS= read -n1 c; do echo ">>>$c<<<"; done >>>a<<< >>> <<< >>>b<<< >>><<< 解决方法
使用hexdump可以让我们准确地看到构成输出的字符,因此稍微更改一下查询可能会有所帮助:
(1)使用正常的IFS和使用-N选项 $(echo 'a b' | while read -N1 c; do c="$c<"; echo -n "$c"; done | hexdump -C) 00000000 61 3c 3c 62 3c 3c |a<<b<<| 00000006 在第一种情况下,0x0a和空格字符的内置读取返回空字符串,因为字符在默认IFS中,并且在输出中忽略IFS中的字符,原因在cdarke的答案中说明. (2)空IFS和-N选项 $(IFS=""; echo 'a b' | while read -N1 c; do c="$c<"; echo -n "$c"; done | hexdump -C) 00000000 61 3c 20 3c 62 3c 0a 3c |a< <b<.<| 00000008 在这种情况下,read内置函数将匹配echo命令输出的四个字符中的每一个,并且在输出中看到0x0a和一个空格,因为对于空IFS,可以将读取的字符分配给局部变量c. (3)使用正常的IFS和-n选项 $(echo 'a b' | while read -n1 c; do c="$c<"; echo -n "$c"; done | hexdump -C) 00000000 61 3c 3c 62 3c 3c |a<<b<<| 00000006 这给出了与case(1)相同的输出,虽然语义有点不同:0x0a和空格字符的内置读取返回空字符串,因为(i)这两个字符都在默认的IFS中( ii)在任何情况下,读内置的-n选项都不会传递尾随的0x0a字符 (4)使用空IFS和-n选项 $(IFS=""; echo 'a b' | while read -n1 c; do c="$c<"; echo -n "$c"; done | hexdump -C) 00000000 61 3c 20 3c 62 3c 3c |a< <b<<| 00000007 在这里我们观察到-n和-N选项之间的差异:使用-n选项,换行特别由read builtin处理并删除,因此从IFS中排除0x0a没有机会允许它传递给局部变量c. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |