Анализ канала -разделенного файла с переменным количеством столбцов и замена отсутствующих столбцов для преобразования в фиксированное количество столбцов

Предупреждение :Это взлом. Таким образом, я не даю никаких обещаний относительно его надежности. Тем не менее, менее вероятно, что ваша система будет повреждена, чем альтернатива .


Чтобы сделать это, мы установим новую копию Debian внутри вашей файловой системы, chrootподключимся к ней для установки некоторых пакетов, а затем создадим своего рода гибридную систему внутри отдельного пространства имен для запуска программы. Для некоторых шагов требуется root-доступ, а для других он должен быть необязательным (, но я еще не разобрался с этим ). Вам понадобится оболочка, debootstrap, chrootиgcc(последняя, ​​потому что нам нужен специальный инструмент ).

Установка минимального экземпляра Debian

Для этого нам понадобится программа с именем debootstrap. Эта программа, как следует из названия, позволяет вам запустить установку Debian. Вы можете установить его с помощью:

sudo apt-get install debootstrap

Теперь, когда это сделано, мы можем перейти к фактической установке.

  1. Во-первых,проверьте, в какой версии Debian находятся нужные вам пакеты.
    Мои находятся в sidна момент написания.
  2. Теперь определите, где вы хотите сохранить этот образ Debian.
    Мне скучно, и я ожидаю, что мне придется делать это более одного раза, поэтому я позвонил своему chroot.0и вставил его прямо в свой CWD (, который также является~).
  3. Запустите эту команду:

    sudo debootstrap --variant=minbase sid chroot.0
    

    замените sidна желаемую версию Debian, а chroot.0на путь к каталогу, который вы хотите использовать.

    Вы также можете использовать use --variant=fakerootи, возможно, избежать использования sudoздесь, но это установит множество дополнительных пакетов (, если вы не сможете объединить --variantс )и может сделать остальные недействительными. ответа из-за проблем с разрешениями.

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

Установка пакетов

Это самая легкая часть. После установки системы вы можете chrootустановить в нее нужные вам пакеты.

  1. chrootв минимальный экземпляр Debian:

    sudo chroot chroot.0
    

    (снова замените chroot.0 на путь, который вы использовали ).

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

    apt install idle-python3.7 python3.7
    
  3. Выйдите из chroot, выполнив exit.

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

Создать инструмент

Сохраните это где-нибудь:

#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
    if (argc < 3) {
        printf(
"This is a single-use, disposable program that binds specified directories from\n"
"a chroot's root to the current root.\n"
"\n"
"Argument #1 should be the path to the chroot directory, sans trailing /.\n"
"Subsequent arguments should be paths relative to the root, with preceeding /.\n"
        );
        return 2;
    }
    for (int i = 2; i < argc; i += 1) {
        char source[PATH_MAX];  /* Not really MAX, but quite big. */
        strcpy(&source, argv[1]);
        strcat(&source, argv[i]);
        if (mount(&source, argv[i],
                  NULL, MS_BIND,
                  NULL) == -1) {
            return 1;
        }
    }
    return 0;
}

и скомпилируйте его сgcc:

gcc bindfromchroot.c -o bindfromchroot

Я назвал это bindfromchroot, потому что это то, что он делает.Причина, по которой мы не можем просто использовать mount --bind, заключается в том, что необходимо как минимум 2 вызова mount; один из них будет скрывать mount, а другой будет скрывать свои библиотеки -, обе из которых прекратят mountработу в последующий раз и оставят нас с неработающим пространством имен, от которого нам придется exitизбавиться.

Теперь, когда все наши настройки завершены, мы можем запустить некоторые команды, которые, вероятно, следует поместить в сценарий оболочки.

Создайте пространство имен и запустите программу

  1. Запустите sudo unshare -m su YOUR_USERNAMEили sudo unshare -m su $(id -un), чтобы запустить оболочку в отдельном пространстве имен от вашего (или текущего пользователя ). Это «отдельное пространство имен» важно; это означает, что когда мы монтируем части нашего минимального экземпляра Debian поверх основного Debian, изменения будут применяться только к нашей новой оболочке и ее дочерним процессам (, а не ко всем процессам ). Может быть хорошей идеей добавить -c /bin/shк команде, потому что bashотображает раздражающие предупреждающие сообщения о том, что что-то происходит катастрофически неправильно после того, как мы выполним следующий шаг.
  2. Запустите инструмент, который вы скомпилировали ранее. Он требует sudoи на самом деле не говорит вам об ошибках, сохраненных через echo $?, но выполняет свою работу. Сколько Debian вам нужно связать, зависит от программы, но я настоятельно рекомендую быть как можно более конкретным и не связывать с /etc, /devили /boot. Чтобы заставить Python 3.7 работать на моей машине, я запустил:

    sudo./bindfromchroot chroot.0 /usr /lib
    
  3. Протестируйте программу, которую хотите запустить, например. idle-python3.7. Если это не работает, проверьте сообщения об ошибках, определите, чего не хватает, exitи повторите попытку с шага 1.

Написание сценария оболочки для автоматического запуска вашей программы

Я потратил на это один -вкладыш. Измените соответствующим образом:

sudo unshare -m su wizzwizz4 -c sh -c 'sudo -S./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

Если вы хотите сохранить переменные среды,вместо этого используйте эту версию:

sudo -E unshare -m su wizzwizz4 -mc sh -c 'sudo -ES./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

Вы можете изменить sudo -ESна sudo -EAдля запуска программы, определенной в переменной окружения SUDO_ASKPASS, которая может быть графической подсказкой (, такой как та, которая предоставляется с git gui), если хотите.

0
20.08.2020, 17:59
2 ответа

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

  • C _A => $3
  • C _B => $5... и так далее
$ awk '
  BEGIN {
    OFS = FS = "|"
    n = split("A-B-C-D-E", x, "-")
    for (i=1; i<=n; ++i) h["C_" x[i]] = 2*(i-1) + 3
  }
  {
    # record which out of
    # ca/cb/.../ce present
    for (i=3; i<NF-2; i+=2) seen[$i] = $(i+1)

    # store fields in preparation
    # for re-filling them based on seen
    nf = split($0, f, FS); $0=""

    # fill up the first two..easy does it
    $(1) = f[1]
    $(2) = f[2]

    # recall which fields c_? 
    # were seen then fill up
    # corresponding field and field value 
    for (var in h) {
      i = h[var]
      if (var in seen) {
        $(i) = var
        $(i+1) = seen[var]
      } else { $(i) = $(i+1) = ""}
    }

    # append the last two fields
    $(NF+1) = f[nf-1]
    $(NF+1) = f[nf]
    # above line **NOT** a typo

    # clear out the array seen
    # for the next iteration
    split("", seen, ".")
  }1
' file

Результаты:

10|100|C_A|val_18|||||C_D|val_20|||50|60
40|200|C_A|val_5|C_B|val_10|C_C|val_30|C_D|val_90|C_E|val_83|40|45
80|100|||||||||C_E|val_90|50|60
0
18.03.2021, 23:11

Считайте переменные поля в массивы, распечатайте массивы, получая пустые строки, если они не используются в строке (не забудьте-F '|'):

BEGIN{
    # initialize expected keys for file (value 1 not used)
    all_keys["C_A"]=1;
    all_keys["C_B"]=1;
    all_keys["C_C"]=1;
    all_keys["C_D"]=1;
    all_keys["C_E"]=1;
 }
 {
    # fill arrays for line
    for(i=3;i<NF-1;i+=2) {
        key[$i]=$i;
        value[$i]=$i+1;
    }
    # first two fields
    printf $1"|"$2"|";
    # all variable key/value pairs, occurring on line or not
    for (k in all_keys) {
        printf key[k]"|"value[k]"|";
    }
    # last two fields
    print $NF-1"|"$NF;
    # delete arrays so we don't carry over values into the next line
    delete key;
    delete value;
}
0
18.03.2021, 23:11

Теги

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