Генерация CSV из текстового файла в командной строке Linux с помощью sed, awk или другого - PullRequest
0 голосов
/ 22 мая 2019

У меня есть файл с тысячами строк, который я хотел бы использовать в качестве csv для дальнейшей обработки.

Исходный файл выглядит следующим образом:

cc_1527 (ILDO_I173_net9 VSSA) capacitor_mis c=9.60713e-16
cc_1526 (VDD_MAIN Istartupcomp_I115_G7) capacitor_mis \
    c=4.18106e-16
cc_1525 (VDD_MAIN Istartupcomp_I7_net025) capacitor_mis \
    c=9.71462e-16
cc_1524 (VDD_MAIN Istartupcomp_I7_ST_net14) \
    capacitor_mis c=4.6011e-17
cc_1523 (VDD_MAIN Istartupcomp_I7_ST_net15) \
    capacitor_mis c=1.06215e-15
cc_1522 (VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_ST_net16) \
    capacitor_mis c=1.37289e-15
cc_1521 (VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_I176_G4) capacitor_mis \
    c=6.81758e-16

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

Окончательный формат CSV для первых 5 строк исходного текста должен быть:

cc_1527,(ILDO_I173_net9 VSSA),capacitor_mis c=9.60713e-16
cc_1526,(VDD_MAIN Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16

Итак, теперь все находится только в одной строке, и символы "\" удалены.

Обратите внимание, что в начале каждой строки могут существовать пробелы, поэтому их следует обрезать, прежде чем что-либо еще будетсделано.

Есть идеи, как этого добиться.?

Заранее спасибо.

С уважением, Педро

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Ответ от @Shawn был принят ОП, и я не уверен, стоит ли публиковать мой ответ, но позвольте мне сделать это только для информации.Если Perl является вашим вариантом, попробуйте следующий скрипт, который сохраняет пробелы в скобках, не заменяя их запятыми:

perl -0777 -ne '
    s/\\\n//g;
    foreach $line (split(/\n/)) {
        while ($line =~ /(\([^)]+\))|(\S+)/g) {
            push(@ary, $&);
        }
        print join(",", @ary), "\n";
        @ary = ();
    }
' input.txt

Вывод:

cc_1527,(ILDO_I173_net9 VSSA),capacitor_mis,c=9.60713e-16
cc_1526,(VDD_MAIN Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16
cc_1524,(VDD_MAIN Istartupcomp_I7_ST_net14),capacitor_mis,c=4.6011e-17
cc_1523,(VDD_MAIN Istartupcomp_I7_ST_net15),capacitor_mis,c=1.06215e-15
cc_1522,(VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_ST_net16),capacitor_mis,c=1.37289e-15
cc_1521,(VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_I176_G4),capacitor_mis,c=6.81758e-16

[Какэто работает]

  • Прежде всего, опция -0777 -ne сообщает Perl, что нужно отбросить все строки в переменную Perl по умолчанию $_.
  • Далее, s/\\\n//g; удаляет завершающие обратные слеши путем слияния строк.
  • Затем split(/\n/) снова разбивает строки на новых строках.
  • Регулярное выражение /(\([^)]+\))|(\S+)/g будет самой важной частью, разделяющей каждую строку на поля.Шаблон поля определяется как: "substring surrounded by parens OR substring which does not include whitespaces." Он работает как FPAT в awk и сохраняет пробелы между паренами, не разделяя на них линию.

Я тестировал с прибл.10000 строк ввода и время выполнения меньше секунды.
Надеюсь, это поможет.

1 голос
/ 23 мая 2019

Использование некоторых более неясных функций sed (он может сделать больше, чем s///):

$ sed -E ':line /\\$/ {s/\\$//; N; b line}; s/[[:space:]]+/,/g' demo.txt
cc_1527,(ILDO_I173_net9,VSSA),capacitor_mis,c=9.60713e-16
cc_1526,(VDD_MAIN,Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN,Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16
cc_1524,(VDD_MAIN,Istartupcomp_I7_ST_net14),capacitor_mis,c=4.6011e-17
cc_1523,(VDD_MAIN,Istartupcomp_I7_ST_net15),capacitor_mis,c=1.06215e-15
cc_1522,(VDD_MAIN,ILDO_LDO_core_Istartupcomp_I7_ST_net16),capacitor_mis,c=1.37289e-15
cc_1521,(VDD_MAIN,ILDO_LDO_core_Istartupcomp_I7_I176_G4),capacitor_mis,c=6.81758e-16

В основном:

  • Считать строку в пространство шаблона.

  • :line /\\$/ {s/\\$//; N; b line}: Если пространство шаблона заканчивается на \, удалите обратную косую черту, прочитайте следующую строку и добавьте ее к пространству шаблона и повторите этот шаг.

  • s/[[:space:]]+/,/g: преобразовать каждый регистр из 1 или более пробельных символов в одну запятую.

  • Распечатайте результат и вернитесь к началу с новой строкой.

...