0

I have files like this:

class SomeClass
    extends anotherClass
    with moreClassA
    with moreClassB {
    //do some crazy stuff
}

I'd like to add one more class to it like this:

class SomeClass
    extends anotherClass
    with moreClassA
    with moreClassB 
    with oneMoreClassIwant {
    //do some crazy stuff
}

I tried to use sed for replacing like this:

sed -E "s/(Class SomeClass[A-Za-z \n]+)\\{/\1with OneMoreClassIWant/" tmp.scala

but it doesn't work for multi-line matching.

I also noticed an example from this post but failed to adapt it to my case.

2
  • The requirement to use sed seems like a complication. This would be somewhat more comfortable in Awk, and pretty straightforward in Perl, where nonstandard sed things like -z are actually reasonably standard if you have Perl in the first place.
    – tripleee
    Commented Dec 31, 2022 at 8:37
  • If the new line (with oneMoreClassIwant) is allowed to appear after the line "class SomeClass" then sed '/class /a with oneMoreClassIwant' should do it.
    – user167612
    Commented Dec 31, 2022 at 17:11

2 Answers 2

1

Using any awk:

$ cat tst.awk
{ rec = rec $0 RS }
END {
    old = \
        "class SomeClass" RS\
        "    extends anotherClass" RS\
        "    with moreClassA" RS\
        "    with moreClassB {" RS\
        "    //do some crazy stuff" RS\
        "}"

    new = \
        "class SomeClass" RS\
        "    extends anotherClass" RS\
        "    with moreClassA" RS\
        "    with moreClassB" RS\
        "    with oneMoreClassIwant {" RS\
        "    //do some crazy stuff" RS\
        "}"

    if ( s = index(rec,old) ) {
        rec = substr(rec,1,s-1) new substr(rec,s+length(old))
    }

    printf "%s", rec
}

$ awk -f tst.awk file
class SomeClass
    extends anotherClass
    with moreClassA
    with moreClassB
    with oneMoreClassIwant {
    //do some crazy stuff
}
0

This seems to work:

xargs -0 < data | sed -z 's/\(class.*\){/\1\n    with anotherMoreClass {/'

or

tr '\n' '\0' < data | sed 's/\(class.*\){/\1\n    with anotherMoreClass {/' | tr '\0' '\n'

You can specify the class name (SomeClass in your case) in this section: \(class.*\) like this:

xargs -0 < data |\
sed -z  's/\(class[[:blank:]]\{1,\}SomeClass.*\){/\1\n    with anotherMoreClass {/'

or

tr '\n' '\0' < data |\
sed 's/\(class[[:blank:]]\{1,\}SomeClass.*\){/\1\n    with anotherMoreClass {/' |\
tr '\0' '\n'
8
  • 1
    sed -z is not portable; it is supported on most Linuxes, but not on many other platforms.
    – tripleee
    Commented Dec 31, 2022 at 8:38
  • 1
    tr '\n' '\0' turns the input into something that is no longer a valid text file and so YMMV with what any subsequent text processing tool (such as sed) might do with it.
    – Ed Morton
    Commented Jan 3, 2023 at 0:21
  • 1
    The issue with \0 is that many tools are written in C and in C a \0 is the "end of string" character and so a variable thats a string can't contain a \0. So, what any given sed, grep, awk, etc. can do with input that contains \0 just depends on whatever whoever implemented that tool decided to do with it. If they can accept it then its just a character, no different than any other (unless they additionally provide an option to use that character as the record terminator instead of \n). Even a command that accepts NULs today could decide not to in their next release though so YMMV
    – Ed Morton
    Commented Jan 3, 2023 at 12:08
  • 1
    @EdMorton Interesting,I had forgotten how C works (about the "end of string"). I tested the same command tr '\0' '\n' | sed ... on busybox and it did not work. So as you said this depends on whatever whoever implemented that tool decided to do with it Commented Jan 3, 2023 at 22:20
  • 1
    The thing is, you cant really tell if "it works" in any given tool since there might be some cases where it doesn't behave as you expect and even if it did work today, it might quietly stop working in the next release (unless it's specifically stated in the documentation for that tool that it will work) since the implementers aren't required to keep doing the same thing consistently across releases for anything that's undefined behavior.
    – Ed Morton
    Commented Jan 4, 2023 at 15:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .