在批处理文件中使用gawk时,我无法将行从格式A重新格式化为格式B [英] Using gawk in a batch file I am having trouble reformatting lines from format A to format B

查看:188
本文介绍了在批处理文件中使用gawk时,我无法将行从格式A重新格式化为格式B的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个生成如下输出的编译器:

I have a compiler which produces output like:

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

例如:

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

我需要使用格式(对于MSVS2013):

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 (

我做得很好,我可以使第一个示例正常工作,但是第二个示例使我感到困惑,因为我没有想到带空格的文件名(谁这样做的!! .这是我的awk(gawk)代码:

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"

好吧,第1点就是一团糟.我将分解以解释我在做什么.首先请注意,输入是一个文件,这是由我的构建生成的错误日志,我将其简单地传递到awk中.另请注意,在任何圆括号之前偶尔会出现"^",因为这是在批处理文件IF语句中,因此我必须转义任何)"-除了其中之一...我不知道为什么! -细分:

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"[(^), ]"-这是用("或)"或,"或"分隔行,当我们考虑带空格的文件时可能会出现问题:(
  • '$2 == "Warning" {...}-第二个参数为警告"的任何行.我尝试使用IGNORECASE = 1,但无法正常工作.同样,我也无法获得警告"或错误"的or表达式,因此我只重复了整个awk行!
  • gsub("<",""^); gsub("\"","");-这是删除'<'和"(双引号),因为MSVS不希望文件名带有引号...而且它似乎无法处理<".如果要获取带空格的文件名,这又是一个问题吗?
  • start=$4"("$6","$7"^) : "$2" "$3":";-这部分基本上将各种参数按插入的各种格式字符串的顺序正确排列.
  • $1=$2=$3=$4=$5=$6=$7=$8=$9="";-嗯...在这里,我想打印第10个参数,此后的每件事,一个窍门(无法使其他参数起作用)是将参数1-9设置为",然后我将打印$ 0.
  • print start $0;-最后一部分,它仅显示我之前建立的字符串"start",后跟第9个参数之后的所有内容(请参见上一点).
  • -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:

  • 如何提取引号之间的文件名,但仍然删除引号
  • 如何获取Line 10(5,7):中的单个数字,如果我将方括号和逗号分开,我可以找到它们,但是最后我从注释中丢失了真实的方括号/逗号.
  • 我可以更高效地打印出第10个元素以及之后的所有元素(而不是$ 1 = $ 2 = ... $ 9 =")
  • 如何将其变成一行,以使$ 2 =="Warning"或"Error"
  • 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"

很抱歉,很长的问题-但是我的awk行变得非常复杂!

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

推荐答案

恕我直言,最好不要让自己陷入正则表达式和花哨的FS值中(如果它们不提供真实值或存在于其他值中)真正需要的方式.只需根据需要剪切并粘贴".将以下内容放入文件

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 
}

然后,根据@EdMorton最出色的评论,运行它

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

 awk -f awkscript  dat.txt > dat.out

输出

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

请注意,我使用了制表符分隔的字段.如果需要空格或其他字符,只需将\t字符替换为" "或任何您需要的字符即可.

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

这篇关于在批处理文件中使用gawk时,我无法将行从格式A重新格式化为格式B的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆