2012-11-07 27 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