2017-06-08 7 views
-2
200005251|AAAAAA 
200005252|BBBBB 
200005261|CCCCCC 
200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 
200005302|VVVVVV 
200005311|AAAAAA 
200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 
200006022|HHHHHH 
200006051|OOOOOO 
200006052|GGGGGG 
200006061|KKKKKK 
200006062|FFFFF 
200006071|TTTTTT 

Ich habe eine Datei im ersten Feld wie oben. Ich muss alle zwei Zeilen zusammenführen, wenn sie nur enden ...... 1 und ...... 2. und lass die anderen so wie es ist. Gewünschter Ausgang:Zwei Linien bedingt verschmelzen

200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD  
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 

Vielen Dank im Voraus.

+0

Was haben Sie versucht, und wie kam es scheitern? – choroba

Antwort

0

awk Lösung:

awk -v RS=" " '{ for(i=1;i<=NF;i++) 
        if ($i~/1$/ && $(i+1)~/2$/) { 
         printf("%s %s\n",$i,$(i+1)); i++; 
        } else { 
         printf("%s\n",$i) 
        } 
       }' file 

Der Ausgang:

200005251 200005252 
200005261 200005262 
200005292 
200005301 200005302 
200005311 200005312 
200006011 
200006021 200006022 
200006051 200006052 
200006061 200006062 
200006071 

Wie Sie Ihre ursprüngliche Eingabe geändert haben - hier ist erweiterte Version:

awk -v RS=" " '{ for(i=1;i<=NF;i++) 
        if ($i~/1\|[[:alpha:]]+$/ && $(i+1)~/2\|[[:alpha:]]+$/) { 
         printf("%s %s\n",$i,$(i+1)); i++; 
        } else { 
         printf("%s\n",$i) 
        } 
       }' file 

Der Ausgang v.2:

200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 

Einzelheiten:

  • -v RS=" " - treat Raum als Datensatz-Trenn statt Newline

  • for(i=1;i<=NF;i++) - durch alle Iterieren Felder

  • if ($i~/1\|[[:alpha:]]+$/ && $(i+1)~/2\|[[:alpha:]]+$/) - Zustand zu prüfen, ob aktuelles Feld 1 am Ende seines ersten Abschnitts und weiter zum nächsten Feld hat 2 am Ende seines ersten Abschnitts

+0

Vielen Dank für Ihre Hilfe und freundliche Erklärung – firefoxix

0

Perl zur Rettung:

perl -nE 'chomp; 
      if ($previous =~ /1$/ and /2$/) { 
       say "$previous $_"; 
       $previous = ""; 
      } else { 
       say $previous if $previous; 
       $previous = $_; 
      } 
      }{ say $previous if $previous 
     ' -- input 

Sie halten die vorherige Zeile in $ vorherigen. Wenn es in 1 endet und die aktuelle Zeile (in $_ von -n gespeichert) in 2 endet, drucken Sie beide in der gleichen Zeile und löschen die $ vorherige; Andernfalls drucken Sie den vorherigen, falls vorhanden, und speichern den aktuellen in $ vorher. Die letzte Zeile gibt die letzte Nummer aus, wenn sie nicht mit der vorherigen Nummer gedruckt wurde.

+0

Das funktioniert aber wenn es nur ein Feld wäre. Ich habe Datei mit zwei Feldern getrennt durch "|" – firefoxix

+0

Versuchen Sie also, es zu ändern, oder stellen Sie eine neue Frage. – choroba

0
awk '{ num[NR]=$1 } END { for (i=1;i<=NR;i++) if (substr(num[i+1],length(num[i+1]))=="2") { printf num[i]"\t"num[i+1]"\n";i++ } else { print num[i] } }' nums 

Wo nums ist die Datei mit der hat Daten. Zuerst setzen wir die Daten in ein Array mit dem Namen num, dann durchlaufen wir die Array-Überprüfung, um zu sehen, ob das nächste Element in zwei endet (mit der Funktion substr zusammen mit der Länge, um das letzte Zeichen zu erhalten). Wenn dies der Fall ist, drucken wir beide und fügen einen hinzu, andernfalls drucken wir einfach das Element.

0

Einfache awk Skript Ihr Ziel erreichen kann,

awk_file:

{ 
    if($1%2==1) { 
    if(odd==1){ 
     printf "\n"; 
    } 
    printf "%s ",$0; 
    odd=1; 
    } else { 
    printf "%s\n",$0; 
    odd=0; 
    } 
} END {printf "\n"} 

Dann führen:

$ awk -v FS='|' -f awk_file file 
200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 
+0

Dies ist eine bessere und allgemeine Vorgehensweise. Kannst du im Klartext erklären, wie dieser Code funktioniert? – firefoxix

+0

Von der Logik, drucken Sie $ 0 \ n, während der extrahierte numerische ist ungerade, und drucken Sie $ 0, wenn es gerade ist. Und noch eine spezielle Regel, wenn das letzte Mal ungerade extrahiert wird, fügen Sie ein '\ n 'vor dem Ausdruck' $ 0 'hinzu – CWLiu