Sed/awk/perl: Text unter Beibehaltung von Teilen ändern und an einer Spalte ausrichten

Sed/awk/perl: Text unter Beibehaltung von Teilen ändern und an einer Spalte ausrichten

Ich habe einen Text wie diesen:

A1JOURNEY0TO1
    .BYTE 00, 00, 00
A2JOURNEY0TO2
    .BYTE 00, 01, 00
A3JOURNEY1TO0
    .BYTE 00, 01, 01

Ich brauche:

JOURNEY_01                               ; 00 TO 01
    .BYTE 00, 00, 00
JOURNEY_02                               ; 00 TO 02
    .BYTE 00, 01, 00
JOURNEY_03                               ; 01 TO 00
    .BYTE 00, 01, 01

und so weiter, wobei „;“ an Zeichen 41 der Zeile stehen muss und die vor und nach „TO“ verwendeten Werte aus den Textzeichenfolgen am Anfang der Zeile übernommen werden.

Antwort1

Die Einzelheiten hängen davon ab, wie variabel Ihre Eingabe ist. Wenn wir davon ausgehen können, dass sie JOURNEYunveränderlich ist und die Zahlen, die Sie hinzufügen möchten, nie mehr oder weniger als zwei Zeichen ( 01-99) lang sein werden, funktioniert Folgendes:

perl -pe 's/^.(\d+)      ## ignore the first character and capture 
                         ## as many digits as possible after it.
            (.+?)        ## Capture everything until the next digit: 'JOURNEY'
            (\d+)TO(\d+) ## Capture the two groups of digits on 
                         ## either side of "TO".
            /            ## End match, begin replacement.

            "$2_" .               ## The 2nd captured group, 'JOURNEY'.
            sprintf("%.2d",$1) .  ## The number, 0-padded.
            " " x 31 .            ## 31 spaces.
            sprintf("; %.2d TO %.2d",$3,$4)  ## The start and end, 0-padded.

            /ex;   ## The 'e' lets us evaluate expressions in the substitution
                   ## operator and the 'x' is only to allow whitespace
                   ## and these explanatory comments
        ' file

Das oben Gesagte lässt sich auch wie folgt zusammenfassen:

perl -pe 's/^.(\d+)(.+?)([\d]+)TO(\d+)/"$2_" . sprintf("%.2d",$1). " " x 31 . sprintf("; %.2d TO %.2d",$3,$4)/e;' file

Wenn auch die Längen der einzelnen Strings variabel sind, müssen Sie dies berücksichtigen:

perl -pe 's/^.+?(\d+)(.+?)([\d]+)TO(\d+)/
          "$2_" . sprintf("%.2d",$1) . 
          " " x (41-length(sprintf("%.2d",$1) . "$2_")) . 
          sprintf("; %.2d TO %.2d",$3,$4)/xe;' file  

Antwort2

Mit awk und erraten, was Sie wünschen

Datei ul.awk (bearbeitet)

/JOURNEY/ { jn=substr($1,2,1) ; x=substr($1,10,1) ; y=substr($1,13) ;
    printf "JOURNEY_%02d%s; %02d TO %02d\n",jn,substr("                                        ",1,31),x,y ;
    next ; }
 {print ;}

und dann laufen

awk -f ul.awk u

JOURNEY_01                               ; 00 TO 01
    .BYTE 00, 00, 00
JOURNEY_02                               ; 00 TO 02
    .BYTE 00, 01, 00
JOURNEY_03                               ; 01 TO 00
    .BYTE 00, 01, 01

Dies ist eine etwas schlechte Codierung, da ich davon ausgegangen war, dass die Zahl immer einstellig ist.

verwandte Informationen