Author Topic: The wonders of Awk  (Read 1972 times)

Offline Ryex

  • Arctic Bird of Programming
  • Global Moderator
  • Chaos Ultimate
  • ****
  • Posts: 5135
  • LV: 198
  • Gender: Male
  • Wants to write a compiler for fun
    • View Profile
The wonders of Awk
« on: June 23, 2014, 06:56:54 AM »
So I've been setting up conky on my linux computer. it's basically a VERY customizable desktop widget but you have to do most of the scripting yourself, pulling information from system commands.

I like to use todo.txt to track my todo list because I can just have it as a simple .txt file in my dropbox and sync it between all my stuff (phone computer ect.)

I wanted to let conky display the todo list but I also wanted it to be appealing which meant I had to parse and insert conky formating into the file before displaying it.

I turned to awk to do it.

the result.
Code: (bash) [Select]
todo.sh -p ls | fold -s -w 40 | awk '
BEGIN{
    BLACK = "${color black}";
    RED = "${color red}";
    GREEN = "${color green}";
    BROWN = "${color brown}";
    BLUE = "${color blue}";
    PURPLE = "${color purple}";
    CYAN = "${color cyan}";
    LIGHT_GREY = "${color LightGrey}";
    DARK_GREY = "${color DarkGrey}";
    LIGHT_RED = "${color LightRed}";
    LIGHT_GREEN = "${color LightGreen}";
    YELLOW = "${color yellow}";
    LIGHT_BLUE = "${color LightBlue}";
    LIGHT_PURPLE = "${color LightPurple}";
    LIGHT_CYAN = "${color LightCyan}";
    WHITE = "${color white}";
    DEFAULT = WHITE;
    LINE_COLOR = DEFAULT;

    PRI_A = YELLOW;
    PRI_B = GREEN;
    PRI_C = LIGHT_BLUE;
    PRI_D = LIGHT_PURPLE;
    PRI_X = DARK_GREY;

    COLOR_PROJECT = LIGHT_GREEN
    COLOR_CONTEXT = CYAN

    COLOR_DATE = RED

    LINEN = 0;
    DONE = 0;
}
/^([0-9]*) (\([A-D]\))? ?x? ?.+$/ {
    sub(/\r$/,"");
    sub(/\n$/,"");

    LINEN += 1
    line = $0
    DONE = 0

    sub(/^([0-9]*) /, "", line)
    
    if(line ~ /^\(A\)/) {
        LINE_COLOR = PRI_A
    } else if (line ~ /^\(B\)/) {
        LINE_COLOR = PRI_B
    } else if (line ~ /^\(C\)/) {
        LINE_COLOR = PRI_C
    } else if (line ~ /^\(D\)/) {
        LINE_COLOR = PRI_D
    } else if (line ~ /^(\(\))? ?x /) {
        LINE_COLOR = PRI_X
        DONE = 1
    } else {
        LINE_COLOR = DEFAULT
    }
    
    if(DONE == 0) {
        sub(/ +\+.+ ?/, sprintf("%s&%s ", COLOR_PROJECT, LINE_COLOR), line)
        sub(/ +@.+ ?/, sprintf("%s&%s ", COLOR_CONTEXT, LINE_COLOR), line)
        gsub(/ +[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]( |$)/, sprintf("%s&%s", COLOR_DATE, LINE_COLOR), line)
    } else {
    }
    

    printf("${goto 8}%s %02d%s %s\n", LIGHT_GREY, LINEN, LINE_COLOR, line)
}
/^[^0-9]+.*$/ && !/--|TODO/ {
    sub(/\r$/,"");
    sub(/\n$/,"");

    line = $0

    if (DONE == 0) {
        sub(/( +|^)\+.+ ?/, sprintf("%s&%s ", COLOR_PROJECT, LINE_COLOR), line)
        sub(/( +|^)+@.+ ?/, sprintf("%s&%s ", COLOR_CONTEXT, LINE_COLOR), line)
        gsub(/( +|^)[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]( |$)/, sprintf("%s&%s", COLOR_DATE, LINE_COLOR), line)
    }

    printf("${goto 24}%s%s\n", LINE_COLOR, line)
}
'

I learned a powerful new tool today, awk is super awesome once you finally figure out how it works, so much easier to use than sed.
« Last Edit: June 23, 2014, 07:35:38 AM by Ryex »
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.

DropBox, the best free file syncing service there is.
(click to show/hide)