У меня есть список в следующем формате:
group1;visitor1,visitor2,visitor3,
group2;visitor4,visitor5
Из приведенного выше списка мне нужно сгенерировать список следующим образом:
group1,visitor1
group1,visitor2
group1,visitor3
group2,visitor4
group2,visitor5
Это очень похоже на Использование AWK для массива и несколько других вопросов. Основная идея состоит в том, чтобы печатать каждое поле, начиная со второго поля, на отдельной строке, предваряя первое поле.
В этом случае мы указываем, что разделителем полей является ,
или ;
, и мы также следим за тем, чтобы не печатать пустые поля (в конце первой строки в заданном поле есть пустое поле данные ). Переменная OFS
, которую мы установили в командной строке с помощью -v
, — это строка-разделитель вывода, которая будет использоваться для разграничения полей вывода, а NF
— количество полей в строке.
awk -F '[,;]' -v OFS=',' '{ for (i = 2; i <= NF; ++i) if ($i != "") print $1, $i }' file
Учитывая данные в вопросе, это генерирует
group1,visitor1
group1,visitor2
group1,visitor3
group2,visitor4
group2,visitor5
Это можно сделать с помощью GNU sed вот так:
sed -r 's:,$::;y:;,:,;:;:l;s:^(([^,]+)[^;]+);:\1\n\2,:;tl' file
Для каждой строки ввода я удаляю завершающую запятую, если она есть, затем заменяю запятые точкой с запятой, чтобы облегчить печать. После этого я запускаю цикл поиска и замены между :l
и tl
, чтобы добавить имя группы к каждому посетителю в текущей строке ввода.