Разделитель Zero/Nul разрывает команду столбца

Здесь есть две проблемы :ваша версия fdiskочевидно не поддерживает таблицы разделов GUID (GPT ), которые использует ваш диск, и ваш диск слишком велик для MBR -разделение на основе.

Причина, по которой вы не можете создать новый раздел, заключается в том, что fdiskвидит защитную MBR, которая настроена на GPT именно для этого сценария :, чтобы инструменты на основе MBR -не испортили ситуацию. макет GPT. fdiskвидит один раздел, занимающий все пространство, к которому он может получить доступ.

Вам необходимо использовать инструмент, совместимый с GPT -, например partedили gparted, если у вас есть графический интерфейс, или gdisk, или совместимый с GPT -fdisk.

2
11.04.2021, 01:22
2 ответа

Is there a way to use \0 as a field/column separator in column ?

Нет, потому что обе реализации column(, о которых я знаю ), которые являются исторической BSD и той, что в пакете util -linux , обе используют стандартные функции манипулирования строками библиотеки C для разбора входных строк, и эти функции работают в предположении, что строки заканчиваются NUL -. Другими словами, байт NUL предназначен для всегда отметки конца строки любой строки.

Optional/ bonus question: Why does column behaves like this (I would expect the \0 to be totally ignored if not managed and the whole line to be printed as a single field) ?

Вдобавок к тому, что я объяснил выше, обратите внимание, что опция -sожидает литеральных символов. Он не анализирует escape-синтаксис, подобный\0(или \n, если это имеет значение ). Это означает, что вы сказали columnсчитать либо \, либо 0допустимыми разделителями для ввода.

Вы можете указать escape-последовательности с помощью строкового синтаксиса $'', если вы используете одну из многих оболочек, которые его поддерживают (, например. он доступен в bash, но не в dash). Так, например, column -s $'\n'будет допустимым (для указания в качестве разделителя столбцов ), если он запускается одной из этих оболочек.

В качестве примечания -мне непонятно, чего вы ожидаете от column. Даже если бы он поддерживал NUL в качестве разделителя, он просто превращал бы каждую строку этого ввода в целый столбец на выходе. Возможно, вы хотели также использовать -t, чтобы упорядочить отдельные поля для каждой строки?

Optional/ bonus question 2: Some data in these columns will be file paths and I wanted to use \0 as a best practice. Do you a have better practice to recommand for storing "random strings" in file without having to escape potential conflictual field separator character they may contain?

Единственное, что я знаю, это префикс каждого поля с его длиной, выраженной в виде текста или двоичного кода, как вы считаете нужным. Но тогда вы, конечно же, не могли бы передать их в column.

Кроме того, если вы беспокоитесь о путях к файлам, вам следует рассмотреть , а не , используя \nлибо в качестве разделителя «структуры», потому что это совершенно допустимый символ для имен файлов.

Так же, как доказательство -концепции -,на основе вашего примера, но с использованием NUL в качестве разделителя структуры/записи и длины -указанных полей :(. Я также немного повозился со строками вашего примера, чтобы использовать многобайтовые символы)

echo -e 'line1\nline2 ò' \ | LC_ALL=C awk '
    BEGIN {
        ORS="\0"
# here we just move arguments away from ARGV
# so that awk reads input from stdin
        for (i in ARGV) {
            c[i]=ARGV[i]
            delete ARGV[i]
        }
    }
    {
# first field is the line read
        printf "%4.4d%s", length, $0
# then a field for each argument
        for(i=1; i<length(c); i++)
            printf "%4.4d%s", length(c[i]), c[i]
        printf "%s", ORS
    }
' "€ column A" $'colu\nmnB' "column C"

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

Тогда гипотетический аналог скрипта вawk(должен быть gawkили mawkдля обработкиRS="\0"):

LC_ALL=C awk '
    BEGIN { RS="\0" }
    {
        nf=0; while(length) {
            field_length = substr($0, 1, 4)
            printf "field %d: \"%s\""ORS, ++nf, substr($0, 5, field_length)
            $0 = substr($0, 5+field_length)
        }
        printf "%s", ORS
    }
'

Обратите внимание, что важно указать одну и ту же локаль для обоих скриптов, чтобы размер символов совпадал. Указание LC_ALL=Cдля обоих допустимо.

2
28.04.2021, 22:53

Ваши столбцы даже не достигли вашей команды awk. Все после первого нуля было потеряно еще до команды echo. Вы не можете хранить двоичный ноль в переменной.

var=$'zzz\x00zzz'
echo "${#var}"
3
var=$'zzz\xFFzzz'
echo "${#var}"
7

Вы можете использовать tr, чтобы изменить все нули на любой другой разделитель по вашему выбору, прежде чем вы даже начнете делать то, что планируете делать.

Или вы можете изменить свою оболочку на zsh.

-2
28.04.2021, 22:53

Теги

Похожие вопросы