What grep command will include the current function name in its output?

前端 未结 9 2157
夕颜
夕颜 2021-01-07 18:08

I run diff with the -p option so the output will include the name of the function where each change occurred. Is there an analogous option for

9条回答
  •  遥遥无期
    2021-01-07 18:34

    I wrote a script to grep C files and show the C function names and signature along with the results. Based on ctags.

    #!/bin/bash
    
    #
    # grep_c_code
    #
    # Grep C files and print the results along with the function name and signature.
    # Requires: ctags, gawk, sed, bash, and you probably want grep too.
    #
    # Written by David Stav, December 19 2012.
    #
    # Released to the public domain.
    #
    
    if [ $# -lt 2 ]; then
        echo "Usage: $0  " >&2
        echo "" >&2
        echo "Example:" >&2
        echo "  $0 'grep --color=always -n -e \"PATTERN\"' file1 file2 dir1 dir2 | less -R" >&2
        exit 1
    fi
    
    GREP_CMD="$1"
    shift
    
    GAWK_SCRIPT="`
    sed -n -e '/^##### START of gawk script #####$/,/^##### END of gawk script #####$/p' \"$0\" | \
    sed -n -e '2,$ { $ D; p}'
    `"
    
    ctags -f - -R --sort=no -n --fields=+afikKmsSzt --extra=+fq "$@" | \
    gawk "$GAWK_SCRIPT" "$GREP_CMD" | \
    bash
    
    exit 0
    
    ##### START of gawk script #####
    function parse_line(a)
    {
        a["tagname"] = $1;
        a["filename"] = $2;
        a["line_number"] = gensub(/^([0-9]+).*$/, "\\1", 1, $3);
        if (a["line_number"] == $3)
        {
            a["line_number"] = "0";
        }
        a["kind"] = gensub(/^.*\tkind:([^\t]+).*$/, "\\1", 1, $0);
        if (a["kind"] == $0)
        {
            a["kind"] = "unknown kind";
        }
        a["signature"] = gensub(/^.*\tsignature:(.*)$/, "\\1", 1, $0);
        if (a["signature"] == $0)
        {
            a["signature"] = "";
        }
    }
    
    function grep_section(a, next_line_number)
    {
        printf("\n");
        printf("\n");
        printf("\n");
        printf("cat '%s' | \\\n", a["filename"]);
        printf("sed -n -e '%s,%sp' | \\\n", a["line_number"], next_line_number);
        printf("%s | \\\n", grep_cmd);
        printf("sed -e '1 i \\\n");
        printf("\\n\\n\\n--\\\n");
        printf("[%s:%s]\\\n", a["filename"], a["line_number"]);
        printf("<%s> %s%s\\\n", a["kind"], a["tagname"], a["signature"]);
        printf("'\n");
    }
    
    BEGIN \
    {
        FS = "\t";
        grep_cmd = ARGV[1];
        ARGV[1] = ""
    }
    
    !/^!/ \
    {
        parse_line(next_line);
        if (a["line_number"])
        {
            next_line_number = next_line["line_number"] - 1;
            grep_section(a, next_line_number);
            delete a;
        }
        for (key in next_line)
        {
            a[key] = next_line[key];
        }
    }
    
    END \
    {
        if (a["line_number"])
        {
            next_line_number = "$";
            grep_section(a, next_line_number);
        }
    }
    ##### END of gawk script #####
    

    Enjoy. :)

提交回复
热议问题