Дублируйте строки 2 раза и перемещайте из строки в столбец - PullRequest
0 голосов
/ 08 сентября 2018

Я хотел бы продублировать каждую строку 2 раза и распечатать значения столбцов 5 и 6 отдельно (транспонировать значения столбцов 5 и 6 из столбца в строку) для каждой строки

Я имею в виду значение в столбце 5 (первая строка) значение в столбце 6 (вторая строка)

Входной файл

08,1218864123180000,3201338573,VV,22,27
08,1218864264864000,3243738789,VV,15,23
08,1218864278580000,3244738513,VV,3,13
08,1218864310380000,3243938789,VV,15,23
08,1218864324180000,3244538513,VV,3,13
08,1218864334380000,3200538561,VV,22,27

Желаемый выход

08,1218864123180000,3201338573,VV,22
08,1218864123180000,3201338573,VV,27
08,1218864264864000,3243738789,VV,15
08,1218864264864000,3243738789,VV,23
08,1218864278580000,3244738513,VV,3
08,1218864278580000,3244738513,VV,13
08,1218864310380000,3243938789,VV,15
08,1218864310380000,3243938789,VV,23
08,1218864324180000,3244538513,VV,3
08,1218864324180000,3244538513,VV,13
08,1218864334380000,3200538561,VV,22
08,1218864334380000,3200538561,VV,27

Я использую этот код для дублирования строк 2 раза, но я не могу выяснить условие со значениями столбцов 5 и 6

awk '{print;print}' file

Заранее спасибо

Ответы [ 4 ]

0 голосов
/ 09 сентября 2018

Это может работать для вас (GNU awk):

awk '{print gensub(/((.*,).*),/,"\\1\n\\2",1)}' file

Заменить последнюю запятую на новую строку, а предыдущие поля за вычетом предпоследнего.

0 голосов
/ 08 сентября 2018

В этом простом случае, когда последнее поле должно быть удалено и помещено в последнюю строку, вы можете сделать

awk -F , -v OFS=, '{ x = $6; NF = 5; print; $5 = x; print }'

Здесь -F , и -v OFS=, установят разделители поля ввода и вывода на запятую соответственно, а код

{
  x = $6    # remember sixth field
  NF = 5    # Set field number to 5, so the last one won't be printed
  print     # print those first five fields
  $5 = x    # replace value of fifth field with remembered value of sixth
  print     # print modified line
}

Этот подход может быть расширен для обработки полей посередине с помощью функции, подобной той, которая содержится в принятом ответе на этот вопрос .

РЕДАКТИРОВАТЬ: Как отмечает Эд в комментариях, запись в NF явно не определена для запуска перестроения $0 (запись всей строки, которую печатает print) в POSIX. стандарт. Приведенный выше код работает с GNU awk и mawk, но с BSD awk (как в * BSD и, вероятно, Mac OS X) он ничего не делает.

Таким образом, чтобы соответствовать стандартам, мы должны быть немного более явными и заставить awk перестраивать $0 из измененного состояния поля. Это можно сделать, назначив любую из переменных поля $1 ... $NF, и обычно используется $1=$1, когда эта проблема возникает в других контекстах (например: когда требуется только разделитель полей) изменилось, но не данные):

awk -F , -v OFS=, '{ x = $6; NF = 5; $1 = $1; print; $5 = x; print }'

Я протестировал это с GNU awk, mawk и BSD awk (это все awk, на которые я могу возлагать руки), и я считаю, что это покрывается битом awk в POSIX , где он говорит: «установка любого другого поля вызывает переоценку $ 0» прямо вверху. Имейте в виду, спецификации могут быть более точными в этом вопросе, и мне было бы интересно проверить, ведут ли себя более экзотические awk так же.

0 голосов
/ 08 сентября 2018

Для многократной печати начала строки для каждого из последних N полей, где N в этом случае равно 2:

$ awk -v n=2 '
    BEGIN { FS=OFS="," }
    {
        base = $0
        sub("("FS"[^"FS"]+){"n"}$","",base)
        for (i=NF-n+1; i<=NF; i++) {
            print base, $i
        }
    }
' file
08,1218864123180000,3201338573,VV,22
08,1218864123180000,3201338573,VV,27
08,1218864264864000,3243738789,VV,15
08,1218864264864000,3243738789,VV,23
08,1218864278580000,3244738513,VV,3
08,1218864278580000,3244738513,VV,13
08,1218864310380000,3243938789,VV,15
08,1218864310380000,3243938789,VV,23
08,1218864324180000,3244538513,VV,3
08,1218864324180000,3244538513,VV,13
08,1218864334380000,3200538561,VV,22
08,1218864334380000,3200538561,VV,27
0 голосов
/ 08 сентября 2018

Не могли бы вы попробовать следующее (учитывая, что ваш Input_file всегда такой же, как показано, и вам нужно каждый раз печатать первые четыре поля, а затем остальные поля (печать по одному вместе с первыми четырьмя)).

awk 'BEGIN{FS=OFS=","}{for(i=5;i<=NF;i++){print $1,$2,$3,$4,$i}}'  Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...