我正在努力创建一个sed regex命令来更改这样的行:
In file included from dira/file_a.h:8, dire/file_e.h:9, and dirf/file_f.h:10,
from dirb/file_b.h:6,
from /existing/abs/path/dirb/file_b.cc:6:
dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
dirc/file_c.h:95: error: 'wave_count_t' does not name a type
dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type
此所需输出:
In file included from /abspaths/dira/file_a.h:8, /abspaths/dire/file_e.h:9, and /abspaths/dirf/file_f.h:10,
from /abspaths/dirb/file_b.h:6,
from /existing/abs/path/dirb/file_b.cc:6:
/abspaths/dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
/abspaths/dirc/file_c.h:95: error: 'wave_count_t' does not name a type
/abspaths/dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type
所以,
我想要的是什么是正则表达式和sed命令?
我正在尝试修改gcc输出,因为包含错误/警告的头文件会生成错误流输出,并引用相对路径,而不是绝对路径。我的XCode IDE调用外部构建系统时,.h文件中出现的错误不是“可点击的”。
答案 0 :(得分:3)
上次修改
我终于成功创建了这样一个命令,仅使用1个命令:
sed 's/^\(.* \)\{0,1\}\([^/ ][^ ]\{1,99\}\.h\)/\1\/abspath\/\2/;' testfile.txt
支持多场比赛......甚至在Mac上也是如此(来自@sudo_O的一些简化想法):
sed -E -e :a -e 's/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/' -e ta testfile.txt
但Mac的sed
实现不支持;
作为命令分隔符。所以我们需要使用多个-e
命令字段。
为了测试它们,我使用以下命令修改了textfile.txt
:
sed -e '4s/^.*$/& &/' -i.bak testfile.txt
(也在Mac上工作)
有两个部分,首先可以计算任何字符串,但以空格结束... 0或1次。第二部分不能以空格或斜线开头,可以包含任何空格而不包含空格,并且必须以.h
结尾。如果匹配,则第一部分(包含前导空格,但如果为0则可能为空)必须跟/abspath/
后面,而不是第二部分。
<强>旧版强>
这不起作用吗?
修改为Mac修改:
sed 's/ \([^/ ][^ ]\{1,99\}\.h\)/ \/abspath\/\1/;' testfile.txt
在Mac和Linux上工作相同。我已将+
替换为{1,99}
。
抱歉,我没有正确地阅读这个问题。这对两者都很好:
sed 's/^\([^/ ][^ ]\{1,99\}\.h\)/\/abspath\/\1/;
s/ \([^/ ][^ ]\{1,99\}\.h\)/ \/abspath\/\1/;' testfile.txt
答案 1 :(得分:2)
Mac和Linux友好:
sed -E 's/^([^/][a-zA-Z/_]+\.h)/\/abspaths\/\1/;s/ ([^/][a-zA-Z/_]+\.h)/ \/abspaths\/\1/g' file
匹配所需的输出:
In file included from /abspaths/dira/file_a.h:8, /abspaths/dire/file_e.h:9, and /abspaths/dirf/file_f.h:10,
from /abspaths/dirb/file_b.h:6,
from /existing/abs/path/dirb/file_b.cc:6:
/abspaths/dirc/file_c.h:88: error: 'eqn_count_t' does not name a type
/abspaths/dirc/file_c.h:95: error: 'wave_count_t' does not name a type
/abspaths/dirc/file_c.h:104: error: ISO C++ forbids declaration of 'WmHyperbolicEqnSet' with no type
说明:
当替换不在线的开头时,需要两次替换以考虑所需的额外空间:
s/^([^/][a-zA-Z/_]+\.h)/\/abspaths\/\1/; # First substitution for start of line
s/ ([^/][a-zA-Z/_]+\.h)/ \/abspaths\/\1/g # Second for non-start of line
# Match (first substitution)
s/
^ - start of line
( - capture group
[^/] - not a forward slash
[a-zA-Z/_]+ - one or more letter, forward slash or underscore
\.h - the extension (escaped)
) - end capture group
# Replace with
/
\/abspaths\/ - the literal string /abspaths (slashes escaped)
\1 - the captured group
/;
# Match (second substitution)
s/
' ' - not start of line but a single space (used quotes here for space)
( - capture group
[^/] - not a forward slash
[a-zA-Z/_]+ - one or more letter, forward slash or underscore
\.h - the extension (escaped)
) - end capture group
# Replace with
/
' ' - put the single space back
\/abspaths\/ - the literal string /abspaths (slashes escaped)
\1 - the captured group
/g - global flag
或者只是通过进行一次替换(基于F.Hauri)答案,但每行只能进行一次匹配:
sed -E 's/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/' file
对于多个匹配sed
支持branching:
sed -E ':a;s/^(.* )?([^/][^ ]+\.h)/\1\/abspath\/\2/;ta' file
答案 2 :(得分:0)
试试这个:
sed "s|\([^\s]*\.h\)|/abspath/\1|" <testfile.txt
忽略绝对路径:
sed "s|^\([^/][^\s]*\.h\)|/abspath/\1|" <testfile.txt