2012-11-07 28 views
2

我有一个C/C++源代码,其中#include语句中的文件名与* .h文件完全不匹配。匹配是正确的,但不区分大小写。这是在Windows系统中发生的源文件的类型。更改#include文件名以匹配大小写

我想要更改所有源文件,以便所有#include语句与它们所引用的文件名完全匹配。

要更改的所有文件名都用引号引起来。

例子:

文件

File1.h 
FILE2.H 
file1.cpp 

file1.cpp

名单
#include "file1.h" 
#include "file2.h" 

变化file1.cpp到

#include "File1.h" 
#include "FILE2.H" 

我想创建一个自动化脚本到达这个更新。

我列出了下面这些步骤中的步骤,但我似乎无法将这些部分放在一起。

  1. 创建所有* .h文件的列表,ls *.h > include.lst。这将创建具有正确大小写的所有文件名的文件。
  2. 使用include.lst中的文件名创建一个sed命令's/<filename>/<filename>/I',它执行不区分大小写的搜索并用正确套用的文件名替换匹配。我相信我只需要进行一次替换,但添加全局g将会处理多次发生。
  3. 将此替换列表应用于目录中的所有文件。

我想建议如何创建sed命令2)给出include.lst。我想我可以处理其余的事情。

+2

使用或考虑您的固定源树符合C lang惯例。使用脚本来生成'mv FILE2.H file2.h'。 JMHO。祝你好运。 – shellter

+0

是的,降低所有文件是最终目标,但一次只能一步。 – KeithSmith

回答

2
  1. 使用sed,或者使用Perl脚本:

    find . -name *.c -print0 | xargs -0 sed -i.bak -e "s/\#include\s\"\([^\"]+/)\"/\#include\s\"\L\1\"/" 
    

    -i.bak将文件备份到original_file_name.bak所以你不必担心,如果你搞砸

    这行更改了C文件中的所有标题包含小写字母。

  2. 然后你想改变所有文件名:

    find . -name *.h -print0 | xargs -0 rename 's/(*)/\L\1/' 
    

    这将重命名所有的头文件为小写。

这仅限于Linux。如果您使用的是Windows,则可能需要在上面使用Perl或Python脚本。

+0

我喜欢将所有文件更改为小写的想法,但版本控制下的源代码会更改许多文件名称,从版本控制角度看,会导致某些文件被删除,而其他文件被删除。需要让版本控制知道文件重命名。 – KeithSmith

+0

@KeithSmith:可以使用与“rename”相同的方法完成。 E.g在Perforce它会是'p4 edit'然后是'p4 move' – MSalters

+0

@MSalters - 是的。 SVN有svn动作。 Git有git mv。 Mercurial有hg重命名。由于我不经常重命名文件,因此我担心的是文件重命名时会丢失历史记录。 – KeithSmith

2
for hfile in $(find /header/dir -type f -iname '*.h'); do 
    sed -i 's/#include "'$hfile'"/#include "'$hfile'"/gI' file1.cpp 
done 

我希望我的报价是正确的:)申请前不用-i

您可以包装sed呼叫另一个循环是这样的:在脚本

for hfile in $(find /header/dir -type f -iname '*.h'); do 
    for sfile in $(find /source/dir -type f -iname '*.cpp'); do 
     sed -i 's/#include "'$hfile'"/#include "'$hfile'"/gI' "$sfile" 
    done 
done 
+0

使用外部双引号进行插值。 – texasbruce

+0

@texasbruce恐怕我不知道你在这里插值的意思。我可以在'sed'命令的任何地方使用双引号,但是我必须在替换中使用双引号。 –

+0

http://en.wikipedia.org/wiki/Variable_interpolation – texasbruce

0

这可能为你工作(GNU SED):

sed 's|.*|s/^#include "&"$/#include "&"/i|' list_of_files | sed -i -f - *.{cpp,h} 
+0

不完整的解决方案,因为必须更改* .h文件中的#include文件以及* .cpp。 – KeithSmith

+0

@KeithSmith只需将'* .h'添加到最后一个命令 – potong

0

感谢您的lowercasing文件名和字符串的#include所有的细节。 但是,我的原始问题是执行字面替换。

以下是符合我的要求的基本命令和sed脚本。

ls *.h *.H | sed -e "s/\([^\r\n]*\)/s\/\\\(\\\#include\\\s\\\"\\\)\1\\\"\/\\\1\1\\\"\/gi/g" >> sedcmd.txt

  1. ls *.h *.H创建的文件列表,同时
  2. 管一条线这份名单的sed。
  3. 搜索整行,这是一个文件名。把整个线组1 s/\(^\r\n]*\)/
  4. 更换整条生产线,文件名,以字符串s/\(\#include\s"\)<filename>"/\1<filename>"/gi

字符串#include<space>"被放置在组1 igi国家也这样做不敏感的情况下,搜索。 g是正常的全球搜索和替换。

给定一个文件名ACCESS.H和cancel.h,脚本的输出

s/\(\#include\s"\)ACCESS.H"/\1ACCESS.H"/gi 
s/\(\#include\s"\)cancel.h"/\1cancel.h"/gi 

最后,SED命令文件可以用命令

sed -i.bak -f sedcmd.txt *.cpp *.h