дд особенность с новыми строками - PullRequest
0 голосов
/ 05 июля 2011

Согласно источникам , которые я прочитал, блок dd просто заменяет символы новой строки пробелами. Это правильно или есть другие вещи на работе.

Утилита unix dd при использовании выглядит так:

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

в файле примерно так:

12
34
56
78
9

т.е.

12\n34\n56\n78\n9\n

Должно дать:

12 34 56 78 9 

Все же это дает

123456789 

1 Ответ

1 голос
/ 05 июля 2011

Текст там немного вводит в заблуждение.

Поскольку вы запросили выходной размер записи два, это именно то, что вы получаете. Новая строка будет заменена пробелами, только если она не превышает размер выходной записи.

Я думаю, что было бы лучше сказать что-то вроде:

Для каждой строки во входном файле выведите байты «cbs», заменив вводную новую строку на достаточное количество пробелов.

Первоначально я думал, что документы могут просто отражать то, как все было сделано в коде, в соответствии с:

  • для каждой строки:
    • заменить символ новой строки в конце пробелом.
    • добавить пробелы к пэду до желаемой длины записи.
    • усечь до желаемой длины записи.

Но на самом деле это не так. Последний исходный код dd имеет это (с добавлением моих собственных комментариев):

/* 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++;
        }
    }
}

Здесь вы явно обрабатываете символ за раз, используя глобальный col для хранения выходного столбца. В нем четко указано, что как только вы находите новую строку во входном потоке, она заменяется пробелами до размера блока преобразования.

И если вы не найдете новую строку до того, как достигнете размера блока преобразования, все остальные символы просто отбрасываются, вплоть до следующей новой строки.

...