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.