问题
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