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