Taztingo
Taztingo

Reputation: 1945

Replace text within searched text using sed and awk?

I have some text in a file that looks like this:

BLAHBLAHBLAH RANDOM DATA
    data = [ 
            #'oink',
            #'bigger oink',
            #'stronger oink',
            #'strongest oink',
            #'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

I'm trying to remove all the #'s within the data array, in my first attempt I tried this:

sed -i "s/#'/'/g" file

This worked great - however, it searched outside of the data[] scope.

I then tried to combine awk with sed:

awk '/data = \[/,/\]/' file | sed -i "s/# '/'/g"

This doesn't work because sed is not getting an input file.

How can I combine these, or how can I do it with one command?

Upvotes: 0

Views: 156

Answers (4)

Ed Morton
Ed Morton

Reputation: 204249

Keep it simple:

awk '/data = \[/{f=1} f{sub(/#/,"")} /\]/{f=0} 1' file

For example, borrowing @anubhava's input and massaging to include a line with a # inside the quoted text:

$ cat file
# text
BLAHBLAHBLAH RANDOM DATA
    data = [
            #'oink',
            #'bigger oink',
            #'stronger oink',
            #'mother #$^*@ oink',
            #'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

            #'stronger oink',
            #'strongest oink',

$ awk '/data = \[/{f=1} f{sub(/#/,"")} /\]/{f=0} 1' file
# text
BLAHBLAHBLAH RANDOM DATA
    data = [
            'oink',
            'bigger oink',
            'stronger oink',
            'mother #$^*@ oink',
            'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

            #'stronger oink',
            #'strongest oink',

The above will work with any awk on any OS.

Upvotes: 1

anubhava
anubhava

Reputation: 785711

Using gnu awk you can do this:

cat file

# text
BLAHBLAHBLAH RANDOM DATA
    data = [
            #'oink',
            #'bigger oink',
            #'stronger oink',
            #'strongest oink',
            #'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

            #'stronger oink',
            #'strongest oink',

# awk command
awk -v RS='data *= *\\[[^]]*\\]' '{gsub(/#/, "", RT); print $0 RT}' ORS= file

# text    
BLAHBLAHBLAH RANDOM DATA
    data = [
            'oink',
            'bigger oink',
            'stronger oink',
            'strongest oink',
            'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

            #'stronger oink',
            #'strongest oink',
            #'beyond godlike oink'

Upvotes: 1

sat
sat

Reputation: 14949

You can try this sed:

sed "/^\s*data = \[/{:loop; /\]/b; n; s/#'/'/g; t loop}" file

Test:

$ sed "/^\s*data = \[/{:loop; /\]/b; n; s/#'/'/g; t loop}" file
BLAHBLAHBLAH RANDOM DATA
    data = [ 
            'oink',
            'bigger oink',
            'stronger oink',
            'strongest oink',
            'beyond godlike oink'
        ]
    BLAHAHAHA RANDOM LASDKFJS DATA

Upvotes: 0

twalberg
twalberg

Reputation: 62459

Something along these lines should work, but note it will replace within any block that starts with data = [ and ends with ]. You didn't really say whether your data file might have multiple such blocks...

awk '/^[ \t]*data = \[[ \t]*$/ { replacing = 1 }
     /^[ \t]*\][ \t]*$/        { replacing = 0 }
     replacing                 { sub("# '\''", "'\''") }
                               { print }
    ' < input.txt > output.txt

Upvotes: 0

Related Questions