在批处理文件中使用 gawk 我无法将行从格式 A 重新格式化为格式 B
Using gawk in a batch file I am having trouble reformatting lines from format A to format B
我有一个编译器产生如下输出:
>>> 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):
<filename-without-quotes>(<line>,<column>) : <error|warning> <code>: <comment>
例如使用上面的第一个例子:
c:\some\file\path\somefile.h(10,5): warning 100: you are missing a (
我做得很好,我可以让第一个例子工作,但第二个例子把我搞砸了,因为我没有想出带有 spaces 的文件名(谁做的! !? >.< ).这是我的 awk (gawk) 代码:
gawk -F"[(^), ]" ' == "Warning" {gsub("<",""^); gsub("\"",""); start="("",""^) : "" "":"; =========""; print start [=11=];}' "Filename_with_build_output.txt"
gawk -F"[(^), ]" ' == "Error" {gsub("<",""^); gsub("\"",""); start="("",""^) : "" "":"; =========""; print start [=11=];}' "Filename_with_build_output.txt"
好的,所以第 1 点是,一团糟。我会分解它来解释我在做什么。首先请注意,输入是一个文件,它是我的构建生成的错误日志,我只是将其传递给 awk。还要注意在任何圆括号之前偶尔出现的“^”是因为这是在批处理文件 IF 语句中所以我必须转义任何“)” - 除了其中一个......我不知道为什么! - 所以细分:
-F"[(^), ]"
- 这是用“(”或“)”或“,”或“”分割行,当我们考虑带有 spaces 的文件时,这可能是一个问题:(
' == "Warning" {...}
- 第二个参数为 "Warning" 的任何行。我尝试使用 IGNORECASE=1 但我无法让它工作。此外,我无法获得 "Warning" 或 "Error" 的 or 表达式,所以我只是简单地用两者重复整个 awk 行!
gsub("<",""^); gsub("\"","");
- 这是为了删除 '<' 和 '"'(双引号),因为 MSVS 不希望文件名周围有引号......而且它似乎无法处理 "< "。如果我想用 spaces? 获取文件名,这里再次出现问题
start="("",""^) : "" "":";
- 这部分基本上将各种参数改组为插入各种格式字符串的正确顺序。
========="";
- 嗯...在这里我想打印第 10 个参数以及之后的所有内容,一个技巧(无法让其他人工作)是将参数 1-9 设置为“”并且然后稍后我将打印 $0.
print start [=20=];
- 最后一部分,它只打印我之前构建的字符串 "start",然后是第 9 个参数之后的所有内容(参见上一点)。
因此,这适用于第一个示例 - 虽然它仍然有点垃圾,因为我得到以下内容(末尾缺少“(”,因为“(”是一个拆分字符):
c:\some\file\path\somefile.h(10,5): warning 100: you are missing a
对于文件名带有 space 的文件,我得到了(你可以看到文件名全被破坏了,一些参数在错误的地方):
RCU(Line,20) : warning 101: : unexpected char a
所以,这里有多个问题:
- 如何提取引号之间的文件名,但仍然删除引号
- 我怎样才能得到
Line 10(5,7):
中的个别数字,如果我在括号和逗号上分开我可以得到它们,但是我在最后的评论中失去了真正的 bracket/commas 。
- 我能否更有效地打印出第 10 个元素和之后的所有元素(而不是 $1=$2=...$9="")
- 我怎样才能把它变成一行,使得 $2 == "Warning" OR "Error"
抱歉问题很长 - 但我的 awk 行变得非常复杂!
恕我直言,最好不要让自己陷入正则表达式和奇特的 FS
值中,如果它们不提供真正的价值或在其他方面确实需要的话。只需 "cut and paste" 即可。将以下内容放入文件中,
{
sub(/^>>> /,"")
warn= " " ; ==""
sub(/^[[:space:]][[:space:]]*/,"",[=10=])
fname=[=10=]
sub(" Line.*$","",fname)
gsub("\"","",fname);
msg=[=10=]
sub(/^.*:/,"",msg)
print fname ":\t" warn ":\t"msg
}
然后,根据@EdMorton 最出色的评论,运行
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
字符替换为 " "
或您需要的任何字符即可。
很多人都渴望单线解决方案,这里是
awk '{sub(/^>>> /,"");warn= " " ; =="";sub(/^[[:space:]][[:space:]]*/,"",[=13=]);fname=[=13=];sub(" Line.*$","",fname);gsub("\"","",fname);msg=[=13=];sub(/^.*:/,"",msg);print fname ":\t" warn ":\t"msg}' dat.txt
IHTH
我有一个编译器产生如下输出:
>>> 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):
<filename-without-quotes>(<line>,<column>) : <error|warning> <code>: <comment>
例如使用上面的第一个例子:
c:\some\file\path\somefile.h(10,5): warning 100: you are missing a (
我做得很好,我可以让第一个例子工作,但第二个例子把我搞砸了,因为我没有想出带有 spaces 的文件名(谁做的! !? >.< ).这是我的 awk (gawk) 代码:
gawk -F"[(^), ]" ' == "Warning" {gsub("<",""^); gsub("\"",""); start="("",""^) : "" "":"; =========""; print start [=11=];}' "Filename_with_build_output.txt"
gawk -F"[(^), ]" ' == "Error" {gsub("<",""^); gsub("\"",""); start="("",""^) : "" "":"; =========""; print start [=11=];}' "Filename_with_build_output.txt"
好的,所以第 1 点是,一团糟。我会分解它来解释我在做什么。首先请注意,输入是一个文件,它是我的构建生成的错误日志,我只是将其传递给 awk。还要注意在任何圆括号之前偶尔出现的“^”是因为这是在批处理文件 IF 语句中所以我必须转义任何“)” - 除了其中一个......我不知道为什么! - 所以细分:
-F"[(^), ]"
- 这是用“(”或“)”或“,”或“”分割行,当我们考虑带有 spaces 的文件时,这可能是一个问题:(' == "Warning" {...}
- 第二个参数为 "Warning" 的任何行。我尝试使用 IGNORECASE=1 但我无法让它工作。此外,我无法获得 "Warning" 或 "Error" 的 or 表达式,所以我只是简单地用两者重复整个 awk 行!gsub("<",""^); gsub("\"","");
- 这是为了删除 '<' 和 '"'(双引号),因为 MSVS 不希望文件名周围有引号......而且它似乎无法处理 "< "。如果我想用 spaces? 获取文件名,这里再次出现问题
start="("",""^) : "" "":";
- 这部分基本上将各种参数改组为插入各种格式字符串的正确顺序。========="";
- 嗯...在这里我想打印第 10 个参数以及之后的所有内容,一个技巧(无法让其他人工作)是将参数 1-9 设置为“”并且然后稍后我将打印 $0.print start [=20=];
- 最后一部分,它只打印我之前构建的字符串 "start",然后是第 9 个参数之后的所有内容(参见上一点)。
因此,这适用于第一个示例 - 虽然它仍然有点垃圾,因为我得到以下内容(末尾缺少“(”,因为“(”是一个拆分字符):
c:\some\file\path\somefile.h(10,5): warning 100: you are missing a
对于文件名带有 space 的文件,我得到了(你可以看到文件名全被破坏了,一些参数在错误的地方):
RCU(Line,20) : warning 101: : unexpected char a
所以,这里有多个问题:
- 如何提取引号之间的文件名,但仍然删除引号
- 我怎样才能得到
Line 10(5,7):
中的个别数字,如果我在括号和逗号上分开我可以得到它们,但是我在最后的评论中失去了真正的 bracket/commas 。 - 我能否更有效地打印出第 10 个元素和之后的所有元素(而不是 $1=$2=...$9="")
- 我怎样才能把它变成一行,使得 $2 == "Warning" OR "Error"
抱歉问题很长 - 但我的 awk 行变得非常复杂!
恕我直言,最好不要让自己陷入正则表达式和奇特的 FS
值中,如果它们不提供真正的价值或在其他方面确实需要的话。只需 "cut and paste" 即可。将以下内容放入文件中,
{
sub(/^>>> /,"")
warn= " " ; ==""
sub(/^[[:space:]][[:space:]]*/,"",[=10=])
fname=[=10=]
sub(" Line.*$","",fname)
gsub("\"","",fname);
msg=[=10=]
sub(/^.*:/,"",msg)
print fname ":\t" warn ":\t"msg
}
然后,根据@EdMorton 最出色的评论,运行
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
字符替换为 " "
或您需要的任何字符即可。
很多人都渴望单线解决方案,这里是
awk '{sub(/^>>> /,"");warn= " " ; =="";sub(/^[[:space:]][[:space:]]*/,"",[=13=]);fname=[=13=];sub(" Line.*$","",fname);gsub("\"","",fname);msg=[=13=];sub(/^.*:/,"",msg);print fname ":\t" warn ":\t"msg}' dat.txt
IHTH