更改 #include 文件名以匹配大小写
Changing #include filenames to match case
我有一个 C/C++ 源代码的主体,其中 #include 语句中的文件名与 *.h 文件不完全匹配。匹配正确,但不区分大小写。这是 Windows 系统中出现的源文件类型。
我想更改所有源文件,以便所有#include
语句都与它们引用的文件名完全匹配。
所有要更改的文件名都括在引号中。
例:
文件列表
File1.h
FILE2.H
file1.cpp
文件1.cpp
#include "file1.h"
#include "file2.h"
将文件 1.cpp 更改为
#include "File1.h"
#include "FILE2.H"
我想创建一个自动脚本来执行此更新。
我在下面列出了这个过程的各个部分的步骤,但我似乎无法将这些部分组合在一起。
- 创建所有 *.h 文件的列表,
ls *.h > include.lst
.这将创建一个大小写正确的所有文件名的文件。 - 使用
include.lst
中的文件名创建一个 sed 命令's/<filename>/<filename>/I'
该命令执行不区分大小写的搜索,并将匹配项替换为大小写正确的文件名。我相信我只需要进行一次替换,但添加全局 g 将处理多次出现。 - 将此替换列表应用于目录中的所有文件。
我想了解如何创建 sed 命令的建议 2) 给定include.lst
.我想我可以处理其余的。
-
在脚本中使用
sed
,或使用 Perl 脚本:find . -name *.c -print0 | xargs -0 sed -i.bak -e "s/#includes"([^"]+/)"/#includes"L1"/"
-i.bak
会将文件备份到original_file_name.bak
因此您无需担心搞砸了此行将 C 文件中的所有标头包含更改为小写。
-
然后,您要更改所有文件名:
find . -name *.h -print0 | xargs -0 rename 's/(*)/L1/'
这会将所有头文件重命名为小写。
这仅适用于 linux。如果您使用的是Windows,则可能需要使用Perl或Python脚本来完成上述所有操作。
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
这可能对你有用(GNU sed):
sed 's|.*|s/^#include "&"$/#include "&"/i|' list_of_files | sed -i -f - *.{cpp,h}
感谢您提供有关小写文件名和 #include 字符串的所有详细信息。 但是,我最初的问题是执行字面替换。
下面是满足我要求的基本命令和 sed 脚本。
ls *.h *.H | sed -e "s/([^rn]*)/s/\(\#include\s\"\)1\"/\11\"/gi/g" >> sedcmd.txt
ls *.h *.H
创建文件列表,一次一行- 通过管道将此列表传送到 sed。
- 搜索整行,这是一个文件名。将整行放在第 1 组中。
s/(^rn]*)/
- 将整行(文件名)替换为字符串
s/(#includes")<filename>"/1<filename>"/gi
字符串#include<space>"
放在组 1 中。gi
州i
进行不区分大小写的搜索。g
是正常的全局搜索和替换。
给定文件名 ACCESS。H 和取消.h,脚本的输出为
s/(#includes")ACCESS.H"/1ACCESS.H"/gi
s/(#includes")cancel.h"/1cancel.h"/gi
最后,sed 命令文件可以与命令一起使用
sed -i.bak -f sedcmd.txt *.cpp *.h
对于包含斜杠的路径名,我的解决方案不会失败(希望您的标题路径中不包含%
符号)。
它也快了几个数量级(几百个文件需要~13秒,而不是等待几分钟)。
#!/bin/bash
shopt -s globstar failglob nocaseglob
# You should pushd to your include path-root.
pushd include/path/root
headers=( **/*.h )
popd
headers+=( *.h ) # My codebase has some extra header files in the project root.
echo ${#headers[*]} headers
# Separate each replacement with ;
regex=""
for header in "${headers[@]}"; do
regex+=';s%#include "'"$header"'"%#include "'"$header"'"%gI'
done
regex="${regex:1}"
find . -type f -iname '*.cpp' -print0 |
xargs -0 sed -i "$regex"
让 sed 每个文件只运行一次要快得多(有许多以 ; 分隔的正则表达式)。
- 既然存在危险,为什么项目要使用-I include开关
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何将更多文件夹添加到c++include路径
- 什么是"#include <boost/functional/hash.hpp> "?
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- C++包含来自 #include "DevEngine/Core.h" 的错误
- <filesystem> 在 clang 6 和 10 上 #include 错误
- 在 void 函数中使用 #include 变量C++
- 切换大小写后如何阻止变量重置?
- 无法找到简单的开关大小写枚举错误
- N-API include an .so or dll
- 仿射密码解密,输出大小写不同
- 允许哪些令牌作为 #include 的参数?
- GCC 包含标头(使用"-include")CMake 未检测到的更改
- 编写宏函数来更改字符串的大小写?
- WebAssembly include OpenCV
- 如何在 c++ 中正确指定 #include 路径以使程序可移植
- 从 4.7 开始的 G++ 忽略了大括号 #include 内名称的大小写
- 更改 #include 文件名以匹配大小写
- 是否有方法使Visual Studio对include区分大小写