'sed' script to convert avr-asm to arm-gnu comments

Viewed 152

I want to convert every occurrence of a ';' into '@', but only if it is not quoted (discard the quotes in this line). The reason behind it:

Assembly language syntax of arm-asm has ';' as the comment sign and everything after a ';' is a comment. Despite of something like ';' or ";".

I suggest the following 'sed' script as a solution and would like to put it to discussion, in case I overlooked something:

File s:

s/^\([^(;\'\")]*\)\(;\)\(.*$\)/\1@\3/

File testcase:

;
  ;
;**********;****
  ';'
  ";"
';'
";"
ABC r1,';'
ABC r1,";"
; ";" ';'
;;;

Usage:

$ sed -f s testcase
@
  @
@**********;****
  ';'
  ";"
';'
";"
ABC r1,';'
ABC r1,";"
@ ";" ';'
@;;

I found that e.g.

        .include "stm32f407.s"        ; target register defines
        .set    PLLP, (DIVP - 2) / 2        ; some other comment

doesn't pass the test.


So hopefully this makes it now:

#!/bin/sh
sed -e "s/^\([^(;\'\")]*\)\(;\)\(.*$\)/\1@\3/" -e "s/^\([^;]*\)\(;\)\(.*\)/\1@\3/"  $1

Caveat: the script works for BSD sed (e.g., macOS), not GNU sed.

2 Answers

With Perl (which is more portable than sed, provided the Perl interpreter is available)

perl -pe 's/(?:\x27;\x27|";")(*SKIP)(*F)|;/@/'
  • (?:\x27;\x27|";")(*SKIP)(*F) any text satisfying (?:\x27;\x27|";") will not be changed, \x27 is single quotes in hexadecimal format
  • |; specify what should be changed as an alternate
  • use the g flag if you want to replace all such occurrences
  • use perl -i.bkp if you want in-place editing (just -i if you don't want a backup)

This might work for you (GNU sed):

sed -E 's/(["'\'']);\1/\1\n\1/g;s/;/@/;y/\n/;/' file

Replace all ; between quotes or double quotes, with newlines.

Replace the first occurrence of ; with @

Replace all newlines with ;.

N.B. To replace all occurrences, use:

sed -E 's/(["'\'']);\1/\1\n\1/g;y/;/@/;y/\n/;/' file

This solution might work with all sed versions:

sed -Ee 'G
        :a
        s/(["'\'']);(\1.*(.))/\1\3\2/
        ta 
        s/;/@/
        :b
        s/(.)(.*\1)$/;\2/
        tb 
        s/.$//' file

It uses the fact an empty hold space appends a newline i.e the G command appends a newline, which can be captured and used in substitutions.

Related