开发者

dd peculiarity with newlines

According to the sources I have read, dd block simply replaces newlines with spaces. Is this correct or are there other things at work.

The unix dd utility when used like so:

dd if=foo.log of=bar.log conv=block cbs=2

on a file like so:

12
34
56
78
9

I.e.

12\n34\n56\n78\n9\n

Should give:

12 3开发者_开发百科4 56 78 9 

Yet it gives

123456789 


The text there is be a little misleading.

Since you've asked for a output record size of two, that's exactly what you're getting. The newline will only be replaced by spaces if it doesn't already exceed the output record size.

I think it would be better to say something like:

For each line in the input, output ‘cbs’ bytes, replacing the input newline with enough spaces as needed.

I originally thought that the docs may simply reflect the way things were done in the code, along the lines of:

  • for every line:
    • replace newline at end with a space.
    • add spaces to pad to desired record length.
    • truncate to desired record length.

But, in fact, it doesn't. The latest dd source code has this (with my own comments added as well):

/* Copy NREAD bytes of BUF, doing conv=block
   (pad newline-terminated records to `conversion_blocksize',
   replacing the newline with trailing spaces).  */

static void copy_with_block (char const *buf, size_t nread) {
    size_t i;

    // For every single character in input buffer.

    for (i = nread; i; i--, buf++) { 
        // If we find a newline.

        if (*buf == newline_character) {
            // If output record no filled up, pad with spaces.

            if (col < conversion_blocksize) {
                size_t j;
                for (j = col; j < conversion_blocksize; j++)
                    output_char (space_character);
            }

            // Regardless, start new output record.

            col = 0;
        } else {
            // No newline.
            // If we hit output limit, increment truncated-lines count.
            // Otherwise only output character if under limit.

            if (col == conversion_blocksize)
                r_truncate++;
            else
                if (col < conversion_blocksize)
                    output_char (*buf);

            // Regardless, increment characters-on-this-line count.

            col++;
        }
    }
}

In this, you're clearly processing a character at a time using a global col to store your output column. It clearly states that as soon as you find the newline in the input stream, it is replaced with spaces up to the conversion block size.

And if you don't find the newline before you hit the conversion block size, al the other characters are simply discarded, up to and including the next newline.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜