Сверните некоторые повторные части последовательных строк

awk '{
  s = m = ""
  for (i = 3; i < NF; i++) {m = m s $i; s = "_"}
  if (m == "") m = "_"
  print $1, $2, m, $NF}'
3
26.06.2014, 02:34
6 ответов

Я не думаю, что вы можете сделать это с sed легко. Проще с perl:

$ perl -F'-' -anle '
    $h{$F[0]} .= defined($h{$F[0]}) ? "&-".$F[1] : "-".$F[1];
    END {
        $,="&";
        print @{[map { $_.$h{$_} } sort { $a <=> $b } keys %h]}
    }
' file
4480-1&-2&-3&-15&4581-1&-2&-3&-4
1
27.01.2020, 21:28

Если Ваши данные не отсортированы, как в вопросе, то сначала Вы должны использовать сортировку -n файл .

awk '
{
    split($1, id, "-")

    if (NR > 1) {
        printf "&"
    }

    if (prefix_test[id[1]]++ == 0) {
        printf("%s", id[1])
    }

    printf("-%s", id[2])
}

END { printf "\n" }' file
0
27.01.2020, 21:28

Должно быть sed, однако здесь perl:

#!/usr/bin/perl

while ( ($a,$b) = split /-/,<>) { $n->{$a}->{"-$b"}++;}

@_ = map { $_,
           map { chomp; "$_&"; } reverse sort { $a <=> $b } keys $n->{$_};
     } sort { $a <=> $b } keys $n;

@_[-1] =~ s/&$//;

print @_;

вывод с числовой сортировкой, не зависящий от порядка ввода:

4480-1&-2&-3&-15&4581-1&-2&-3&-4
0
27.01.2020, 21:28

Решение для awk, которое не требует сортировки записей по префиксу

awk -F- '
    {a[$1] = !a[$1]? $1"-"$2 : a[$1]"&-"$2} 
END {asort(a); for (i in a) printf "%s&", a[i]}
' file | sed 's/&$/\n/'

Если вам не нужно сортировать вывод -, вы можете опустить asort(a)

awk -F- '
    {a[$1] = !a[$1]? $1"-"$2 : a[$1]"&-"$2} 
END {for (i in a) printf "%s&", a[i]}
' file | sed 's/&$/\n/'
0
27.01.2020, 21:28

Это должно сработать:

awk -F- '$1!=a{printf "%s", $1} {printf "-%s&", $2} {a=$1}' file | sed 's/&$/\n/g'

Выход:

4480-1&-2&-3&-15&4581-1&-2&-3&-4

Объяснение:

  • awk -F- разделитель: -
  • $1! =a{printf "%s", $1} выведите первую часть 4480, если она не совпадает с последней обработанной строкой
  • {printf "-%s&", $2} выведите вторую часть с помощью & в конце
  • {a=$1} установите a в обработанную строку
  • sed 's/&$/\n/g' удалите последний символ, который является & и добавьте новую строку
1
27.01.2020, 21:28

Вероятно, это невозможно с sed. Я делаю с AWK. Я предполагаю одну запись в строке.

awk '
  BEGIN { FS="-"; ORS=""; left="" }

  {
    if(NR>1){print "&"}

    # Only print left part if it differs from previous line
    if ($1!=left) {
      print $1 "-" $2
      left=$1;
    } else {
      print "-" $2
    }
  }' inputfile.txt

Выходы 4480-1 & -2 & -3 & -15 & 4581-1 & -2 & -3 & -4

0
27.01.2020, 21:28

Теги

Похожие вопросы