我需要在超出可用存储空间和内存的字节流末尾填充NUL字节,这样输出长度就可以被N整除。
#!/bin/sh
generate_arbitrary_length | paddingN | work_with_padded
N=8192的工作代码:
padding8192(){ dd status=none bs=8192 conv=sync ; }
但是对于较小的N,减少拷贝块大小要慢 * 个数量级 *,这并没有完成:
padding4(){ dd status=none bs=4 conv=sync ; }
复制输入流后,我可以使用wc
和dd
表示计数和填充:
padding4(){ { { tee /dev/fd/3 >&2 ; } 3>&1 | wc -c | { read -r isize ; pad=$(( 4 - isize % 4)) ; [ 0 -lt $pad ] && dd status=none if=/dev/zero bs=$pad count=1 >&2 ; } } 2>&1 ; }
已经快多了。但是很难读懂--谁能说清为什么填充在EOF结束呢?
有更好的办法吗?
虽然我只需要保留存储字节计数模字长所需的状态,但我想不出使用shell内置函数的简单而高性能的实现。使用GNU coreutils/cpio/tar,没有编译器/perl/特性,这将不同于busybox/dash/bash。我还没有提出一个awk
的解决方案,因为我未能使它在二进制输入上表现良好(G/s),没有均匀的NL/NULL分隔成行。
2条答案
按热度按时间db2dz4w81#
既然你提到有编译器可用,这里有一个小型的,可移植的C程序。它没有得到任何更快和内存经济。它甚至是可读的大多数人在编程社区。如果没有,你总是可以洒
/* Comments! */
。:-)实际应用:
如果你担心非POSIX编译器选项
-x c
,你可以很容易地把C程序写到pad.c
并从那里编译它。fwrite
,fread
和putchar
的高级错误处理留给读者。注意here-document是如何避免main解析参数的,甚至可以传递PAGE_SIZE这样的字符串,如果stdio默认允许的话。
我刚刚意识到,像这样编译C和漂亮的awk脚本没有太大区别--awk也编译内部程序,然后执行它。还有什么比编译到机器的CPU并运行可执行文件更好的呢?
irlmq6kh2#
POSIX要做的事情是使用临时文件。