假设我们有一个至少有2个换行符的字符串,我们需要将它分解为三个字符串,其中第一个可能包含换行符,但以下两个不能。为什么在本例中'read'不接受 0作为分隔符?
$ echo -ne '1\n2\n3\n4\n5' |\
sed -rn '1h; 2,$ H; # Combine all strings in hold space
${g; # hold space → pattern space
s/^(.*)\n([^\n]+)\n([^\n]+)$/\1\x00i\x00ii/g;
p}' >/tmp/h
$ hexdump -C /tmp/h
00000000 31 0a 32 0a 33 00 69 00 69 69 |1.2.3.i.ii|
0000000a
现在,我们可以用hexdump看到数据是正确的。但是,如果我们将这些字符串置于内置读取中,则不会按预期工作。
$ read -d $'\0' a b c < /tmp/h \
&& echo -e "---$a---\n+++$b+++\n===$c==="
---1---
+++2+++
===3===
与实际指令相同
$ read -d $'\0' a b c < <(echo -ne '1\n2\n3\n4\n5' |\
sed -rn '1h; 2,$ H;
${g;s/^(.*)\n([^\n]+)\n([^\n]+)$/\1\x00i\x00ii/g;p}');\
echo -e "---$a---\n+++$b+++\n===$c==="
---1---
+++2+++
===3===
更多乐趣:它不把换行符作为分隔符
echo ' - - - - - - - - - - - - - - - - - No delimiter'
unset a b c
read a b c < <(seq 1 18 | sed -rn '4,+2 p')
echo -e "---${a:-not set}---\n---${b:-not set}---\n---${c:-not set}---"
echo ' - - - - - - - - - - - - - - - - - Delimiter is $ \n '
unset a b c
read -d $'\n' a b c < <(seq 1 18 | sed -rn '4,+2 p')
echo -e "---${a:-not set}---\n---${b:-not set}---\n---${c:-not set}---"
echo ' - - - - - - - - - - - - - - - - - Delimiter is "$ \n"'
unset a b c
read "-d $'\n'" a b c < <(seq 1 18 | sed -rn '4,+2 p')
echo -e "---${a:-not set}---\n---${b:-not set}---\n---${c:-not set}---"
echo ' - - - - - - - - - - - - - - - - - Delimiter is $ \0 '
unset a b c
read -d $'\0' a b c < <(seq 1 18 | sed -rn '4,+2 p')
echo -e "---${a:-not set}---\n---${b:-not set}---\n---${c:-not set}---"
输出:
- - - - - - - - - - - - - - - - - No delimiter
---4---
---not set---
---not set---
- - - - - - - - - - - - - - - - - Delimiter is $ \n
---4---
---not set---
---not set---
- - - - - - - - - - - - - - - - - Delimiter is "$ \n"
---4---
---5---
---6---
- - - - - - - - - - - - - - - - - Delimiter is $ \0
---4---
---5---
---6---
不,我没有改变IFS。
GNU bash,版本4.2.45(1) - 发行版(x86_64-pc-linux-gnu)。
GNU sed的版本4.2.1
我们可以推测的是,分隔符被存储为空终止字符串,并且该'read'逻辑失败的未初始化和显然空区分值,并在这两种情况下回退到“IFS”分裂。也许提交一个错误报告? – tripleee
它应该在bash中工作。看到这个http://mywiki.wooledge.org/BashFAQ/020 –
@ aleks-daniel-jakimenko所以这是我应该报告的错误? //也用newline测试更新我的文章 – tijagi