Объединение столбцов в файл с помощью Awk

Входные данные:

ABC,SSSD,12345,NSS,12345,xxx,TS11 ,,,,,,TS21 ,,,,,,TS22 ,,,,,,BS26 ,,,,,,GPRS ABC,SSSD,12356,NSS,12356,xxx,TS11 ,,,,,,TS21 ,,,,,,TS22 ,,,,,,GPRS ,,,,,,BS26 

Вывод:

 ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26 

Я уже пробовал написать сценарий ниже. Но это интенсивно работает:

 #!/bin/bash head -2 $1 | tail -1 >> $1"_output" sed '1,2d' $1 > temp$1.txt cp temp$1.txt $1 rm -f temp$1.txt while IFS='' read -r line || [[ -n $line ]]; do # echo "main line -- "$line # echo "prev line -- "$prevLine service=`echo $line | cut -d "," -f1` value=`echo $line | cut -d "," -f7` if [ "$service" != "" ] then if [ "$prevLine" != "" -a "$mvalue" != "" ] then echo $prevLine$mvalue >> $1"_output" fi prevLine=$line mvalue="" else #echo $value mvalue=$mvalue"|"$value #echo $mvalue fi done < "$1" echo $prevLine$mvalue >> $1"_output" 

Может ли кто-нибудь предложить лучший способ сделать это с помощью awk или любого лучшего метода?

  • помочь исправить заявление awk
  • Сценарий BASH AWK добавляет дни до фиксированной даты
  • Что делает следующий скрипт?
  • замените символ из строки, которая находится между первым и вторым поиском, используя sed или awk
  • Как сохранить переменные awk в области видимости?
  • Как напечатать максимальное значение, если оно выше, сравните с медианным значением других, используя большой набор данных
  • Как мне перебирать строки в STDIN и запускать команду оболочки?
  • Кудрявая скобка путаницы!
  • 5 Solutions collect form web for “Объединение столбцов в файл с помощью Awk”

    Если вы не слишком суетливы в отношении пробелов, вы делаете это с помощью двух правил awk:

      awk '$1 { printf "\n" $0 } !$1 { printf OFS $7 }' FS=, OFS='|' infile 

    Это оставляет пустую строку в начале вывода и пропускает один в конце. Чтобы исправить это, добавьте предложения if и END :

     awk '$1 { if(NR>1) printf "\n"; printf $0 } !$1 { printf OFS $7 } END { printf "\n" }' FS=, OFS='|' infile 

    Вывод:

     ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26 

    Изменить – заметьте о% в $ 0

    Как заметил Гленн в комментариях, если ваши строки содержат % , безопаснее вызывать printf со строкой формата, например:

     awk '$1 { if(NR>1) printf "\n"; printf "%s", $0 } !$1 { printf OFS"%s", $7 } END { printf "\n" }' FS=, OFS='|' infile 

    Пока количество линий для слияния является постоянным awk просто можно решить, какой тип строки он имеет, глядя на номер строки:

     $ awk -F, '1==NR%5 { printf $0 "|";next } { printf $7 (NR%5?"|":"\n") }' DATA ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26 

    если его всегда будет одинаковое количество строк (5), комбинация paste и sed может сделать:

     paste -d',' - - - - - <file | sed 's/,\{2,\}/|/g' 

    будет 1) paste 5 строк в один, используя в качестве разделителя, 2) заменить несколько (2 или более) запятых на одну трубу

    Другое sed :

     sed ':;N;s/\n,,,*/|/;t;P;D' file 

    Подобный ответ Тору, но сохраняет строку до ее завершения:

     awk -F, ' $1 != "" {if (record) print record; record = $0} $1 == "" {record = record "|" $NF} END {if (record) print record} ' file 

    Если вы хотите использовать bash, вы можете сделать

     lines=() while IFS= read -r line; do if [[ ${line:0:1} == "," ]]; then # the line starts a comma lines[-1]+="|${line##*,}" # strip the commas and append to # the last element of the array else lines+=("$line") # append the line to the array fi done <<"$1" printf "%s\n" "${lines[@]}" 
     ABC,SSSD,12345,NSS,12345,xxx,TS11|TS21|TS22|BS26|GPRS ABC,SSSD,12356,NSS,12356,xxx,TS11|TS21|TS22|GPRS|BS26 
    Interesting Posts

    Проблемы с обновлением apt-get

    Включение многоадресной связи между двумя процессами JVM AIX

    Как сопоставить идентификаторы ataX.0 в сообщениях kern.log на реальных устройствах / dev / sdY?

    Как перезаписать каталог в нескольких местах с одним исходным каталогом

    Как найти следующий доступный суффикс файла (file_a.txt file_b.txt и т. Д.)

    Демон высокого уровня планировщика

    Как установить коды клавиш вручную в vim?

    Опасность ядра

    Есть ли способ заставить COMPREPLY выводиться как вертикальный список слов вместо одной строки?

    печать данных на основе строк в формате таблицы в Linux

    fglrx, вызывающий «исправление рекурсивной ошибки, но требуется перезагрузка» на гибридной графике Intel / AMD

    Как сказать «UN * X или * nix» в разговоре или чтении вслух?

    Таинственные экземпляры bash с использованием большого количества процессоров, как я могу отлаживать?

    Преобразование одного загрузочного одиночного жесткого диска в RAID 1 без его удаления

    Сервис и поддержка Systemd Initrd

    Linux и Unix - лучшая ОС в мире.