Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 更改包含正则表达式的头文件_Regex_Sed - Fatal编程技术网

Regex 更改包含正则表达式的头文件

Regex 更改包含正则表达式的头文件,regex,sed,Regex,Sed,我更改了文件名,所以我必须更改包含的文件名。 例如,我将alpha.h更改为fix_alpha.h。所以我必须改变 #包括“alpha.h” 到 #包括“fix_alpha.h” 但是要修复的文件太多了,比如beta.h到fix_beta.h 我尝试使用reg exp来修复它 grep -rl '*' ./ | xargs sed -i 's/*\.h``/fix_*\.h/g' 但它不起作用。 我应该如何编写reg exp以使其工作 find -name '*.h' -exec sed -i

我更改了文件名,所以我必须更改包含的文件名。 例如,我将alpha.h更改为fix_alpha.h。所以我必须改变
#包括“alpha.h”
#包括“fix_alpha.h”
但是要修复的文件太多了,比如beta.h到fix_beta.h 我尝试使用reg exp来修复它

grep -rl '*' ./ | xargs sed -i 's/*\.h``/fix_*\.h/g'
但它不起作用。 我应该如何编写reg exp以使其工作

find -name '*.h' -exec sed -i 's~alpha.h~fix_alpha.h~' {} \;

您的代码可能包含
/
,因此这里使用
~
分隔符您的
grep
命令查找包含
*
的文件(并且大多数C文件可能至少有一条注释,因此所有C文件(源文件和头文件)都将被选中)。不过,你可以做得更好。例如,假设需要映射的名称是
alpha.h
beta.h
gamma.h
、和
delta.h
,并且您是一名正常的健全程序员,在文件名或目录名中都没有空格或换行符,那么您可以使用以下命令生成感兴趣的文件列表:

grep -rlE '^#include[[:space:]]*"(alpha|beta|gamma|delta)\.h"' .
然后,对于每个这样的文件,您需要将这些头名称替换为
fix.
前缀。现在,您需要确定您的
sed
是否具有扩展正则表达式。假设没有,那么您可以创建一个
sed
脚本来为您进行映射。例如,创建包含以下内容的文本文件
映射标题

alpha.h
beta.h
gamma.h
delta.h
现在,使用(当然)
sed
将其制作成
sed
脚本:

sed -e 's/\.h/\\.h/' \
    -e 's%.*%s/^#include[[:space:]]*"&"/#include "fix_&"/' \
    mapped-headers > script.sed
现在,您可以使用以下方法将该脚本应用于包含要映射的任何标题的文件:

grep -rlE '^#include[[:space:]]*"(alpha|beta|gamma|delta)\.h"' . |
xargs sed -i.bak -f script.sed
(如果您使用
-i
选项在Mac OS X上覆盖文件,则必须提供备份后缀,该后缀可以附加到
-i
选项,如图所示,或附加到单独的选项中;如果您不想添加后缀,只想覆盖,则必须在Mac上写入
-i'
。相反,如果您使用GNU
sed
,则备份后缀为是可选的,但如果存在,则必须将其附加到
-i
选项。显示的内容在两种平台上都适用。并非所有版本的
sed
都支持
-i
选项进行覆盖。)

至少对于
sed
脚本部分来说,使用简单前缀映射扩展到100个头应该是显而易见的。您也可以使用
sed
脚本生成
grep
脚本;它在精神上类似,但比所示的脚本更简单

您可以编写更高级的正则表达式来匹配
#include
指令的异常布局。您可能会在
#
之前和
#
之后留出空格。如果在
#include
行的操作部分有注释,那么您会遇到比映射名称更大的问题。此代码不处理:

/* comments? */    #    \
include /*
    */   "alpha.h"
但无论如何,没有一个理智的人会写这样的代码

此外,如果您有一些不完全系统化的重命名要做,您可以修改脚本来处理,方法是将
映射的头文件更改为在单独的列中包含“old”和“new”值:

alpha.h    alphabet.h
beta.h     veg/carotene.h
gamma.h    hard/radiation.h
delta.h    v-wing.h
它怎么不起作用了? 无论如何,你的正则表达式对我来说似乎没有意义。我相信你可以用

sed 's|^\(\s*#\s*include\s.*[*/"]\)\([^/"]*\)\.h\(".*\)$|\1fix_\2.h\3|'
       \                          / \       /    \     /
           lines start with          header      everything
           #include, match           filename    after .h
           until the " or / 
           before the header 
           filename
例如:

#include "foo.h"
# include "foo.h"
   #  include "foo.h"
#include "foo/bar.h"
#include "foo/bar.h"    // something else
结果

#include "fix_foo.h"
# include "fix_foo.h"
   #  include "fix_foo.h"
#include "foo/fix_bar.h"
#include "foo/fix_bar.h"    // something else
保持简单:

find . -type f -print | xargs sed -i 's/#include "/&fix_/'

find.-name'*.h'-print0 | xargs-r0n1 sed-e的|“alpha.h”|“fix|u alpha.h”| g;'-i
您是否试图更改文件名或内容?请注意,您的问题并不真正是关于C的;您没有迹象表明希望编写一个C程序来进行正则表达式映射(可能是件好事-您应该模拟
sed
)。我已经用
sed
重新标记了它-您可以添加
grep
xargs
,尽管它们不是必需的。源文件中标题的外观也需要修复;这只会查找标题文件,并假设每个标题都包含目标标题。如果搜索正则表达式和替换字符串都不存在,则如果包含斜杠,您当然仍然可以使用斜杠分隔符。分隔符的选择完全是任意的,因此
~
当然也很好。