Pat Res
Pat Res

Reputation: 97

Select a range of text using one of the built-in UNIX tools

My target file is python module and looks like this:

def function_one(arg):
    """docstring"""

    code
    code
    code


def function_two(arg):
    """docstring"""

    code
    code
    code

What I'm trying to achieve is to get the body of function_one using either awk, sed or grep.

The way I want to approach this is to select a range of text between the function name and two blank lines (since every function definition ends with two blank lines).

What I've come up with so far is an awk command that selects text from the function name up until the first blank line: awk '/def function_one/,/^$/' module.py.

However that only produces this text, since there's a blank line between my docstring and the function body:

def function_one(arg):
    """docstring"""

How should I go about defining a range starting with a string an ending with precisely two blank lines?

Upvotes: 0

Views: 70

Answers (4)

Daweo
Daweo

Reputation: 36630

If you do not mind having trailing empty line, you might do as follow, let file.txt content be:

def function_one(arg):
    """docstring"""

    code
    code
    code


def function_two(arg):
    """docstring"""

    code
    code
    code

then

awk '{curr=length($0);if(prev==0 && curr==0)exit;prev=curr;print}' file.txt

output:

def function_one(arg):
    """docstring"""

    code
    code
    code

Explanation: I use prev to store length of whole line, if prev line length and current line length are 0 then stop processing. For every line just print it.

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 204035

$ cat tst.awk
/^def[[:space:]]+function_one\(/ { inBlock=1 }
inBlock {
    if ( !NF && !pNF ) {
        prtBlock()
        block = ""
        inBlock = 0
    }
    else {
        block = block $0 ORS
        pNF = NF
    }
}
END { if (inBlock) prtBlock() }

function prtBlock() {
    sub(/\n+$/,"",block)
    print block
}

$ awk -f tst.awk file
def function_one(arg):
    """docstring"""

    code
    code
    code

Upvotes: 1

vgersh99
vgersh99

Reputation: 965

how about - with GNU awk:

gawk -v RS='\n\n\n' '/function_one/' myFile

Upvotes: 0

Raman Sailopal
Raman Sailopal

Reputation: 12887

Using awk and "def" as the record separator:

awk -v RS="def" '/function_one/ { print "def "$0 }' module.py

Upvotes: 0

Related Questions