Using gawk in a batch file I am having trouble reformatting lines from format A to format B

对着背影说爱祢 提交于 2020-01-05 04:14:12

问题


I have a compiler which produces output like:

>>> Warning <code> "c:\some\file\path\somefile.h" Line <num>(x,y): warning comment

For example:

>>> Warning 100 "c:\some\file\path\somefile.h" Line 10(5,7): you are missing a (
>>> Warning 101 "c:\some\file\path\file with space.h" Line 20(8,12): unexpected char a

I need to get the into the format (for MSVS2013):

<filename-without-quotes>(<line>,<column>) : <error|warning> <code>: <comment>

e.g. using the first example from above:

c:\some\file\path\somefile.h(10,5): warning 100: you are missing a (

I have had a good go at it and I can just about get the first example working, but the second example screwed me over because I had not figured on filenames with spaces (who does that!!? >.< ). Here is my awk (gawk) code:

gawk -F"[(^), ]" '$2 == "Warning" {gsub("<",""^); gsub("\"",""); start=$4"("$6","$7"^) : "$2" "$3":"; $1=$2=$3=$4=$5=$6=$7=$8=$9=""; print start $0;}' "Filename_with_build_output.txt"
gawk -F"[(^), ]" '$2 == "Error"   {gsub("<",""^); gsub("\"",""); start=$4"("$6","$7"^) : "$2" "$3":"; $1=$2=$3=$4=$5=$6=$7=$8=$9=""; print start $0;}' "Filename_with_build_output.txt"

Ok, so point 1 is, its a mess. I will break it down to explain what I am doing. First note that the input is a file, which is an error log generated by my build which I simply pass into awk. Also note the occasional "^" before any round bracket is because this is within a batch file IF statement so I have to escape any ")" - except for one of them... I don't know why! - So the breakdown:

  • -F"[(^), ]" - This is to split the line by "(" or ")" or "," or " ", which is possibly an issue when we think about files with spaces :(
  • '$2 == "Warning" {...} - Any line where the 2nd parameter is "Warning". I tried using IGNORECASE=1 but I could not get that to work. Also I could not get an or expression for "Warning" or "Error", so I simply repeat the entire awk line with both!
  • gsub("<",""^); gsub("\"",""); - this is to remove '<' and '"' (double quotes) because MSVS does not want the filename with quotes around it... and it can't seem to handle "<". Again issues here if I want to get the filename with spaces?
  • start=$4"("$6","$7"^) : "$2" "$3":"; - this part basically shuffles the various parameters into the correct order with the various format strings inserted.
  • $1=$2=$3=$4=$5=$6=$7=$8=$9=""; - hmm... here I Wanted to print the 10th parameter and every thing after that, one trick (could not get others to work) was to set params 1-9 to "" and then later I will print $0.
  • print start $0; - final part, this just prints the string "start" that I built up earlier followed by everything after the 9th parameter (see previous point).

So, this works for the first example - although its still a bit rubbish because I get the following (missing the "(" at the end because "(" is a split char):

c:\some\file\path\somefile.h(10,5): warning 100: you are missing a

And for the one with filename with a space I get (you can see the filename is all broken and some parameters are in the wrong place):

RCU(Line,20) : warning 101: : unexpected char a

So, multiple issues here:

  • How can I extract the filename between the quotes, yet still remove the quotes
  • How can I get at the individual numbers in Line 10(5,7):, if I split on brackets and comma I can get to them, but then I lose real bracket/commas from the comment at the end.
  • Can I more efficiently print out the 10th element and all elements after that (instead of $1=$2=...$9="")
  • How can I make this into one line such that $2 == "Warning" OR "Error"

Sorry for long question - but my awk line is getting very complicated!


回答1:


IMHO, it is better not to get yourself tied up in reg-ex and fancy FS values if they don't provide real value or are in other ways really needed. Just "cut and paste" as needed. Put the following in a file,

  {
    sub(/^>>> /,"")
    warn=$1 " " $2; $1=$2=""
    sub(/^[[:space:]][[:space:]]*/,"",$0)
    fname=$0
    sub(" Line.*$","",fname)
    gsub("\"","",fname);
    msg=$0
    sub(/^.*:/,"",msg)
    print fname ":\t" warn ":\t"msg 
}

Then, per @EdMorton 's most excellent comments, run it

 awk -f awkscript  dat.txt > dat.out

output

c:\some\file\path\somefile.h:    Warning 100:     you are missing a (
c:\some\file\path\file with space.h:     Warning 101:     unexpected char a

Note that I have used tab separated fields. If you what spaces or other chars, just sub the \t chars with " " or whatever you need.

As so many crave the one-liner solution, here it is

awk '{sub(/^>>> /,"");warn=$1 " " $2; $1=$2="";sub(/^[[:space:]][[:space:]]*/,"",$0);fname=$0;sub(" Line.*$","",fname);gsub("\"","",fname);msg=$0;sub(/^.*:/,"",msg);print fname ":\t" warn ":\t"msg}'  dat.txt

IHTH



来源:https://stackoverflow.com/questions/45986210/using-gawk-in-a-batch-file-i-am-having-trouble-reformatting-lines-from-format-a

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!