
Это файл 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 ofnon=
characters, слева от которого виден либо горизонтальный пробел,\h
либо начало строки^
. Затем они выводятся с помощьюOFS
$,
set to a запятая. - Для всех строк (включая первую) мы извлекаем значения полей с помощью регулярного выражения,
/="([^"]*)"/g
которое следует читать как извлечение строки, заключенной в двойные кавычки (предполагая, что нет экранированных двойных кавычек), которые находятся рядом со знаком равенства слева. Затем набор этих значений объединяетсяstdout
с помощьюOFS
. - В случае
while
решения с циклом мы сначала считываем строку как есть, без разбиения на слова. Затем мы устанавливаем IFS на=
и отклоняем первое поле. Теперь все поля будут иметь формат"..."...
Затем мы используемexpr
утилиту, чтобы конкретизировать значение в двойных кавычках и поместить их в$@
массив. В конце циклаfor
мы удаляем исходные элементы ($N
), затем то, что остается, это то, что нам нужно. Наконец, они объединяются запятой посредством установки IFS на запятую и расширения$*
.