Home > front end >  How to get awk print function name and comment
How to get awk print function name and comment

Time:12-27

Hello awk ninjas I need some help, so I found a solution to print defined function names from my shell script from here but my issue I would love my functions to show the comments... here is an example of how my functions are defined.

function1() { # this is a function 1
          command1
        }

function2() { # this is a function 2
          command2
        }

function3() { # this is a function 3
          command3
        }

So the command provided that works is this one: typeset -f | awk '/ \(\) $/ && !/^main / {print $1}' and the output will be this:

function1
function2
function3

But I would love the output to be this way (a 4 space between the function name and comment would be really nice also):

function1    # this is a function 1
function2    # this is a function 2
function3    # this is a function 3

Thank you in advance.

CodePudding user response:

Writing as an answer to have better formatting capabilities. You could try to use a custom, "dummy" variable and store a comment in it.

Let's declare our function:

test_function () {
  __COMMENT="TEST_FUNCTION"
}

I used __COMMENT variable as our placeholder. Notice, that bash will print the function name and the variable in 2 lines, so we have to use a state machine in our awk code:

typeset -f | awk \
'match($0, /__COMMENT="[^"]*/) {
    if (functionname) {
        print functionname ": " substr($0, RSTART 11, RLENGTH-11)
    }
}

/ \(\) {$/ && !/^main / {functionname=$1}'

From the end:

/ \(\) {$/ && !/^main / {functionname=$1}

I had to modify Your patter to match my output, so You may need to remove the brace character to make it work on Your side. It will look for a function declaration and store its name as functionname.

'match($0, /__COMMENT="[^"]*/) {

It will look for our variable. Notice, that the length of __COMMENT=" is 11. We will need it.

if (functionname) {
    print functionname ": " substr($0, RSTART 11, RLENGTH-11)
}

If functionname is set it prints the name and a substring of our match skipping 11 characters from the beginning and 1 from the end (quotes).

CodePudding user response:

Try to send your output through this pipeline:

grep '() ' | grep -v '^main' | sed '/() { /s//    /'

Explanation: the first grep finds all the lines containing a function definition with () . The second one filters out the main() function. Finally, the sed command replaces the string () { by four spaces.

For testing purpose, I put the input you described above into a file s.txt containing:

function1() { # this is a function 1
          command1
        }

function2() { # this is a function 2
          command2
        }

function3() { # this is a function 3
          command3
        }

main() { # this is the main function
          commands
        }

when I run

cat s.txt | grep '() ' | grep -v '^main' | sed '/() { /s//    /'

I get this output:

function1    # this is a function 1
function2    # this is a function 2
function3    # this is a function 3

CodePudding user response:

Replace each # with ::

function1() { : this is a function 1
          command1
        }

function2() { : this is a function 2
          command2
        }

function3() { : this is a function 3
          command3
        }

$ typeset -f | awk '/ \() $/{fn=$1} /^ *:/{ print fn $0 }'
function1    : this is a function 1;
function2    : this is a function 2;
function3    : this is a function 3;

Change the awk script as you like to match whatever other function layouts you have and/or tweak the output however you prefer.

See What is the purpose of the : (colon) GNU Bash builtin? for more info.

  • Related