Объединить строки на основе первого столбца без разделителя - PullRequest
0 голосов
/ 26 сентября 2019

Мне нужно объединить все строки с одинаковым значением в первом столбце.

Входной файл имеет следующий вид:

34600000031|(1|1|0|1|1|20190114180000|20191027185959)
34600000031|(2|2|0|2|2|20190114180000|20191027185959)
34600000031|(3|3|0|3|3|20190114180000|20191027185959)
34600000031|(4|4|0|4|4|20190114180000|20191027185959)
34600000015|(1|1|100|1|8|20190114180000|20191027185959)
34600000015|(2|2|100|2|9|20190114180000|20191027185959)
34600000015|(3|3|100|3|10|20190114180000|20191027185959)
34600000015|(4|4|100|4|11|20190114180000|20191027185959)

Мне удалось частично добиться этого с помощью следующего:

awk -F'|' '$1!=p{if(p)print s; p=$1; s=$0; next}{sub(p,x); s=s $0} END{print s}' INPUT

Вывод следующий:

34600000031|(1|1|0|1|1|20190114180000|20191027185959)|(2|2|0|2|2|20190114180000|20191027185959)|(3|3|0|3|3|20190114180000|20191027185959)|(4|4|0|4|4|20190114180000|20191027185959)
34600000015|(1|1|100|1|8|20190114180000|20191027185959)|(2|2|100|2|9|20190114180000|20191027185959)|(3|3|100|3|10|20190114180000|20191027185959)|(4|4|100|4|11|20190114180000|20191027185959)

Что мне нужно (и я не могу найти как) это следующее:

34600000031|(1|1|0|1|1|20190114180000|20191027185959)(2|2|0|2|2|20190114180000|20191027185959)(3|3|0|3|3|20190114180000|20191027185959)(4|4|0|4|4|20190114180000|20191027185959)
34600000015|(1|1|100|1|8|20190114180000|20191027185959)(2|2|100|2|9|20190114180000|20191027185959)(3|3|100|3|10|20190114180000|20191027185959)(4|4|100|4|11|20190114180000|20191027185959)

Я мог бы сделать sed после начального awk, но я не верю, что это правильноеспособ сделать это.

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Вам также необходимо подставить разделитель в значения.Ваши исправления awk выглядели бы так:

awk -F'|' '$1!=p{if(p)print s; p=$1; s=$0; next}{sub(p "\\|",x); s=s $0} END{print s}'

, но также неплохо бы сопоставить начало строки:

awk -F'|' '$1!=p{if(p)print s; p=$1; s=$0; next}{sub("^" p "\\|",x); s=s $0} END{print s}'

Я бы сделал это несколько проще, поскольку использует больше памяти (какон хранит все в массиве), но не нуждается в сортировке файла:

awk -F'|' '{ k=$1; sub("^" $1 "\\|", ""); a[k] = a[k] $0 } END{ for (i in a) print i "|" a[i] }'

Для каждой строки запомните первое поле, замените первое поле на |, затем добавьте егок массиву, проиндексированному первым полем.В конце выведите каждый элемент массива с ключом, разделителем и значением.

0 голосов
/ 26 сентября 2019
$ awk -F'|' '
    {
        curr = $1
        sub(/^[^|]+\|/,"")
        printf "%s%s", (curr==prev ? "" : ors curr FS), $0
        ors = ORS
        prev = curr
    }
    END { print "" }
' file
34600000031|(1|1|0|1|1|20190114180000|20191027185959)(2|2|0|2|2|20190114180000|20191027185959)(3|3|0|3|3|20190114180000|20191027185959)(4|4|0|4|4|20190114180000|20191027185959)
34600000015|(1|1|100|1|8|20190114180000|20191027185959)(2|2|100|2|9|20190114180000|20191027185959)(3|3|100|3|10|20190114180000|20191027185959)(4|4|100|4|11|20190114180000|20191027185959)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...