Intereting Posts
OpenVPN: Маршрутизация по названию адреса или порту, а не по IP Сделать содержимое терминала соответствующим размеру окна Как проверить, является ли данный путь файлом или каталогом Перезапустите процесс, когда я получу stderr из другого процесса остановить фледору gnome авто-поворот экрана при встряхивании ноутбука? Как сконфигурировать имя устройства для шифрования корневого раздела с Grub2? Vim и унифицированные разности Как изменить адрес электронной почты Postfix отправляет как Затвердевающий дебиан? Поведение ping с частичной потерей пакетов на Ubuntu SSH странное поведение входа – возможно, человек в средней атаке Экран i3 гаснет после 5 минут бездействия Как загрузиться с помощью grub2 rescue promt в систему UEFI? Кросс-компилировать gdb для mips и сделать исполняемый файл небольшим, как в OpenWrt найти набор общих файлов между несколькими каталогами?

Как объединить первые две строки CSV столбец за столбцом?

У меня есть файл Excel, который я преобразовал в CSV. После преобразования это выглядит как в следующем примере (обратите внимание, что в CSV есть более 100 столбцов. Это уменьшенная версия):

,Product," ",Citty," ",Price ,Name," ",Location," ",Per Unit ,banana," ",CA," ",5.7 ,apple," ",FL," ",2.3 

Мне нужно написать скрипт, который будет брать первую и вторую строку и «объединять» их вместе на основе их запятой:

 ,Product Name," "" ",Citty Location," "" ",Price Per Unit ,banana," ",CA," ",5.7 ,apple," ",FL," ",2.3 

Я рассмотрел другие вопросы здесь и переполнение стека, но ответы, похоже, не относятся к этой странной ситуации столбец за столбцом только для первых 2 строк файла.


В качестве дополнительной несвязанной задачи я также хотел бы избавиться от пустых столбцов в csv и исправить ошибку орфографии, чтобы она выглядела так:

 Product Name,City Location,Price Per Unit banana,CA,5.7 apple,FL,2.3 

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

Я буду получать CSV с орфографической ошибкой несколько раз, поэтому я хотел бы программно исправить ошибку в сценарии. Также обратите внимание, что столбцы не всегда могут быть в указанном выше порядке, поэтому мне нужно динамически проверять каждое имя столбца на наличие ошибок во время сценария.

Попробуй это

 $ awk -F, 'NR<2{split(gensub(/Citty/,"City","g",$0),a,FS)}NR==2{for(b=2;b<=NF;b+=2){c=ca[b]" "$b","}print gensub(/,$/,"",1,c)}NR>2{print gensub(/(^,|" *",)/,"","g",$0)}' inp Product Name,City Location,Price Per Unit banana,CA,5.7 apple,FL,2.3 $ 

Этот же код более читабелен, если разделить его на несколько строк:

 $ awk -F, ' > NR<2{split(gensub(/Citty/,"City","g",$0),a,FS)} > NR==2{for(b=2;b<=NF;b+=2){c=ca[b]" "$b","}print gensub(/,$/,"",1,c)} > NR>2{print gensub(/(^,|" *",)/,"","g",$0)}' inp Product Name,City Location,Price Per Unit banana,CA,5.7 apple,FL,2.3 $ 

Если 1-я строка, разбейте ее на элементы массива в пределах. Исправьте опечатку Citty-> City.

Если 2-я строка, начиная со 2-го столбца, вывести соответствующий столбец из 1-й строки вместе с этим столбцом. Повторите для каждого столбца с шагом в 2 столбца. Снимите конечный.

После 2-й строки замените любой начальный или любой "", пустой строкой, а затем напечатайте результат.

Протестировано нормально на GNU Awk 4.0.2

Попробуйте онлайн!

Используя Perl, с Text :: CSV и MoreUtils:

 perl -MText::CSV -MList::MoreUtils=pairwise -lne ' BEGIN { $p = Text::CSV->new(); } @f = $p->fields() if $p->parse($_); @hdr = map { s/Citty/City/ ; $_ } @f if $. == 1; @f = pairwise { $a . " " . $b } @hdr, @f if $. == 2; print join ",", grep { /\w/ } @f if $. > 1; ' file.csv Product Name,City Location,Price Per Unit banana,CA,5.7 apple,FL,2.3 

В grep пропущены поля, которые не содержат хотя бы один символ слова.

С perl> = 5.14.0 вы можете упростить замену на map s/Citty/City/r @f используя модификатор неразрушающего замещения .

Пытаться

  awk -F, ' {gsub (/,*"[ ]*",*/, ",") sub (/^,/, "") sub (/Citty/, "City") } NR == 1 {n = split ($0, T) next } NR == 2 {for (;n; n--) $n = T[n] " " $n } 1 ' OFS=, file Product Name,City Location,Price Per Unit banana,CA,5.7 apple,FL,2.3