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

Если вам необходимо использовать kvm / qemu, вы обнаружите, что производительность не будет высокой. (В будущем, пожалуйста, опубликуйте более подробную информацию, например о версии дистрибутива и kvm, это может помочь) Изменить: забыл добавить, что если ваш qemu / kvm поддерживает spice, вам, вероятно, следует попробовать это. Кроме того, вам следует попробовать все видеодрайверы, чтобы увидеть, какой из них дает вам лучшую производительность, как видно из гостевой системы (например, лучший fps с использованием glxgears):

-vga [std|cirrus|vmware|qxl|xenfb|none]

Лучшим выбором для гостевой производительности под Linux, вероятно, является cirrus, qxl или vmware. . IIRC, spice использует qxl.

В качестве альтернативы вы можете попробовать переслать графическое приложение на хост по сети, используя:

  • Virtual GL - довольно сложно настроить, но 3D будет отображаться на хосте (так что он может использовать преимущества ваша видеокарта для выполнения работы)
  • Xpra - намного проще, но не так быстро ..
  • NX, VNC и т. д. Все они используют сеть для пересылки дисплея в качестве видеодрайвер в qemu / kvm просто не поддерживает ускорение 3d / gl / xv ..

0
27.08.2018, 23:01
2 ответа

awk может работать с данными фиксированной ширины. Сначала нам нужно определить ширину столбцов:

fieldwidths=$(head -n 1 file | grep -Po '\S+\s*' | awk '{printf "%d ", length($0)}')

Это значение"36 26 7 9 7 "--последнее поле больше 7 символов. Произвольно сделаем его 70 символов:

fieldwidths=${fieldwidths/% /0}

Теперь давайте прочитаем данные и превратим их в CSV:

awk -v FIELDWIDTHS="$fieldwidths" '{
    for (i=1; i<=NF; i++) {
        val = $i
        sub(/ *$/, "", val)
        gsub(/"/, "\"\"", val)
        printf "%s\"%s\"", (i==1 ? "" : ","), val
    }
    print ""
}' file

выходы:

"Id","Name","Type","Size","Created"
"1sV3_a1ySV0-jbLxhA8NIEts1KU_aWa-5","info.pdf","bin","10.0 B","2018-08-27 20:26:20"
"1h-j3B5OLryp6HkeyTsd9PJaAtKK_GYyl","2018-12-ss-scalettapass","dir","","2018-08-27 20:26:19"

Та же функциональность с perl

perl -lne '
    if ($. == 1) {
        @head = ( /(\S+\s*)/g );
        pop @head;
        $patt = "^";
        $patt.= "(.{". length($_). "})" for @head;
        $patt.= "(.*)\$";
    }
    print join ",", map {s/"/""/g; s/\s+$//; qq("$_")} (/$patt/o);
' file
3
28.01.2020, 02:23

Вы можете сделать это с помощью Perlс помощью функции unpack, создав шаблон распаковки динамически, изучив заголовок (1-я строка):

perl -lpe '
    $fmt //= join "", map("A". length(), /\H+\h+(?=\H)/g), "A*";
    $_ = join ",", map { s/"/""/gr =~ s/(.*)/"$1"/r } unpack $fmt;
' input-file.txt

Пояснение:

  • -pзаставит perlпотреблять файл на основе -строк. Каждая строка, также известная как запись, обозначается как $_. Другой эффект -pзаключается в том, что он автоматически печатает текущую запись, прежде чем перейти к выборке следующей.
  • -lделает 2 вещи, устанавливаетORS = RS = \n
  • Регулярное выражение /\H+\h+(?=\H)/gдолжно извлекать все поля, кроме последнего, а затем они передаются в map.
  • mapвычисляет длины этих полей и добавляет к каждому префикс «А».
  • Вместо того, чтобы не выбирать последнее поле выше, мы добавляем ловушку -all "A *".
  • Затем они передаются в join, который склеивает их вместе в строку, используя нулевой разделитель. Таким образом, формат распаковки готов к использованию и больше не вычисляется из-за оператора //=, который является функцией defined-or.
  • Теперь, вооружившись динамически созданным форматом распаковки, мы приступаем к применению к каждой строке, включая заголовок.
  • unpackраспаковывает строку, в нашем случае текущую строку, используя предоставленный формат, и выдает распакованные поля.
  • Эти испускаемые поля затем вводятся в map, который работает с каждым -за -единицей и выполняет шаги, описанные в коде {... }. В нашем случае в каждом поле мы делаем следующее :a )удваиваем двойные кавычки. b )заключите поле в двойные кавычки.
  • После того, как mapзакончит редактирование полей, он перебрасывает их в join, который объединяет их с помощью запятой ,и формирует небольшой CSVфайл.
  • П.С.: Обратите внимание, что нам не нужно было обрезать конечные пробелы в полях, сгенерированных unpack, потому что unpackделает это за вас при использовании символа форматированияA(A для ASCII ).

Выход:

"Id","Name","Type","Size","Created"
"1sV3_a1ySV0-jbLxhA8NIEts1KU_aWa-5","info.pdf","bin","10.0 B","2018-08-27 20:26:20"
"1h-j3B5OLryp6HkeyTsd9PJaAtKK_GYyl","2018-12-ss-scalettapass","dir","","2018-08-27 20:26:19"

Это можно сделать с помощью инструмента sed, но потребуется двухпроходный -подход, в котором сначала, используя строку заголовка ввода, мы динамически генерируем скрипт sed, который затем работает с входной файл (, включая заголовок )для выполнения желаемой операции, как показано:

if="input-file.txt"
cmd=$(< "$if" head -n 1 | perl -lne 'print join $/, reverse map { $s += length();qq[s/./\\n/$s] } /\H+\h+(?=\H)/g')
sed -e '
    '"${cmd}"'
    s/"/""/g
    s/[[:blank:]]*\n/","/g
    s/.*/"&"/
' < "$if"
3
28.01.2020, 02:23

Теги

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