#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;
).