Пробуждение нескольких преобразований / разделителей за один раз

#csv #awk

Вопрос:

Я должен преобразовать (предварительно обработать) файл CSV, создав / вставив новый столбец, являющийся результатом объединения существующих столбцов.

Например, преобразование:

 A|B|C|D|E
 

в:

 A|B|C|D|C > D|E
 

В этом примере я делаю это с помощью:

 cat myfile.csv | awk 'BEGIN{FS=OFS="|"} {$4 = $4 OFS $3" > "$4} 1'
 

Но теперь мне нужно сделать кое-что более сложное, и я не знаю, как это сделать.

Я должен преобразиться:

 A|B|C|x,y,z|E
 

в

 A|B|C|x,y,z|C > x,C > y,C > z|E
 

Как это можно сделать эффективно с помощью awk (или другой команды) (мой csv-файл может содержать тысячи строк)?

Спасибо.

Комментарии:

1. Если C, x, y или z могут содержать/содержать любой метасимвол регулярного выражения или amp; или \1 , обязательно проверьте их с помощью любого решения, использующего функцию *sub ().

Ответ №1:

С GNU awk (для gensub которого есть расширение GNU):

 awk -F'|' '{$6=$5; $5=gensub(/(^|,)/,"\1" $3 " > ","g",$4); print}' OFS='|'
 

Ответ №2:

Вы можете разделить 4-е поле на массив:

 awk 'BEGIN{FS=OFS="|"} {split($4,a,",");$4="";for(i=1;i in a;i  )$4=($4? $4 "," : "") $3 " > " a[i]} 1' myfile.csv
A|B|C|C > x,C > y,C > z|E
 

Комментарии:

1. Это пока единственное решение, которое будет работать для любых символов/строк в $3 или $4, так как оно просто использует операции с литеральными строками.

Ответ №3:

Есть много способов сделать это, но самый простой заключается в следующем:

 $ awk 'BEGIN{FS=OFS="|"}{t=$4;gsub(/[^,] /,$3" > amp;",t);$4 = $4 OFS t}1'
 

мы делаем копию четвертого поля в переменной t . Там мы заменяем каждую строку, которая не содержит нового разделителя ( , ), содержимым третьего поля, за которым следует > исходная совпадающая строка ( amp; ).