Необходимо отформатировать вывод в формате CSV

Необходимо отформатировать вывод в формате CSV

Это файл abc.txt

NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"

Нужен вывод в формате ниже с abc.csv

NAME    StartTime   TotalElapsedTime    Pool    ThreadsReached
MARK    14:11:26.710583     0       10      0
MARK    14:11:26.710583     0       10      0

решение1

Так как базовый формат CSV предполагает запятую ,в качестве разделителя полей, используйте следующий GNUседподход:

sed -e '1iNAME,StartTime,TotalElapsedTime,Pool,ThreadsReached' -e 's/[^=]*="\([^"]*\)"/\1,/g; s/,$//g' file

Выход:

NAME,StartTime,TotalElapsedTime,Pool,ThreadsReached
MARK,14:11:26.710583,0,10,0
MARK,14:11:26.710583,0,10,0

1i- вставкизаголовокстрока перед первой строкой файла

s/[^=]*="\([^"]*\)"/\1,/g- извлечение всех значений атрибутов

решение2

while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift; N=$#
   for arg
   do
      set -- ${1+"$@"} "$(expr " $arg" : ' "\(.*\)"')"
   done
   shift "$N"; IFS=,; echo "$*"
done < abc.txt

while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift
   while case ${#} in 1 ) break ;; esac; do
      expr " $1" : ' "\(.*\)"'
      shift
   done | tr \\n ,; expr " $*" : '.*"\(.*\)"'
done < abc.txt

perl -lne '$,=",";
   print /(?:^|\h)\K[^=]*/g if $. == 1;
   print /="([^"]*)"/g;
' abc.txt

Пояснения

  • В коде Perl из первой строки мы извлекаем имена полей с помощью регулярного выражения, /(?:^|\h)\K[^=]*/gкоторое читается как get me the run of non=characters, слева от которого виден либо горизонтальный пробел, \hлибо начало строки ^. Затем они выводятся с помощью OFS $,set to a запятая.
  • Для всех строк (включая первую) мы извлекаем значения полей с помощью регулярного выражения, /="([^"]*)"/gкоторое следует читать как извлечение строки, заключенной в двойные кавычки (предполагая, что нет экранированных двойных кавычек), которые находятся рядом со знаком равенства слева. Затем набор этих значений объединяется stdoutс помощью OFS.
  • В случае whileрешения с циклом мы сначала считываем строку как есть, без разбиения на слова. Затем мы устанавливаем IFS на =и отклоняем первое поле. Теперь все поля будут иметь формат "..."...Затем мы используем exprутилиту, чтобы конкретизировать значение в двойных кавычках и поместить их в $@массив. В конце цикла forмы удаляем исходные элементы ( $N), затем то, что остается, это то, что нам нужно. Наконец, они объединяются запятой посредством установки IFS на запятую и расширения $*.

Связанный контент