Einige wiederholte Teile aufeinanderfolgender Zeilen zusammenfassen

Einige wiederholte Teile aufeinanderfolgender Zeilen zusammenfassen

Ich habe Daten im Editor wie diese:

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

Können wir das mit einer For-Schleife oder so machen? Mit sed?

Meine erforderliche Ausgabe ist4480-1&-2&-3&-15&4581-1&-2&-3&-4

Antwort1

Das sollte funktionieren:

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

Raus:

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

Erläuterung:

  • awk -F-Trennzeichen ist-
  • $1!=a{printf "%s", $1}Drucken Sie den ersten Teil 4480, wenn dieser nicht mit dem in der letzten verarbeiteten Zeile übereinstimmt.
  • {printf "-%s&", $2}Drucken Sie den zweiten Teil mit &am Ende
  • {a=$1}setze a auf die verarbeitete Zeile
  • sed 's/&$/\n/g'Entfernen Sie das letzte Zeichen, das ein ist &, und fügen Sie eine neue Zeile hinzu

Antwort2

Ich glaube nicht, dass das so einfach geht sed. Einfacher geht es mit 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

Antwort3

Mit sed wahrscheinlich nicht möglich. Ich mache es mit AWK. Ich gehe von einem Eintrag pro Zeile aus.

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

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

Antwort4

Sollte sed sein, hier ist jedoch 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 @_;

numerisch sortierte Ausgabe, unabhängig von der Eingabereihenfolge:

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

verwandte Informationen