Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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
C++ 更改包含文件名以匹配大小写_C++_C_Sed - Fatal编程技术网

C++ 更改包含文件名以匹配大小写

C++ 更改包含文件名以匹配大小写,c++,c,sed,C++,C,Sed,我有一段C/C++源代码,其中include语句中的文件名与*.h文件不完全匹配。匹配项是正确的,但不区分大小写。这是Windows系统中出现的源文件类型 我想更改所有源文件,以便所有include语句都与它们引用的文件名完全匹配 所有要更改的文件名都用引号括起来 例如: 文件清单 File1.h FILE2.H file1.cpp file1.cpp #include "file1.h" #include "file2.h" 将file1.cpp更改为 #include "File1.h"

我有一段C/C++源代码,其中include语句中的文件名与*.h文件不完全匹配。匹配项是正确的,但不区分大小写。这是Windows系统中出现的源文件类型

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

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

例如:

文件清单

File1.h
FILE2.H
file1.cpp
file1.cpp

#include "file1.h"
#include "file2.h"
将file1.cpp更改为

#include "File1.h"
#include "FILE2.H"
我想创建一个自动脚本来执行此更新

我在下面列出了这一过程的各个步骤,但我似乎无法将这些步骤组合在一起

创建所有*.h文件的列表,ls*.h>include.lst。这将创建一个包含所有大小写正确的文件名的文件。 使用include.lst中的文件名创建sed命令的///I,该命令执行不区分大小写的搜索,并用大小写正确的文件名替换匹配项。我相信我只需要做一次替换,但添加全球g将解决多次发生的问题。 将此替换列表应用于目录中的所有文件。 我想了解有关如何创建sed命令2的建议,请参见include.lst。我想我能处理剩下的事

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
我希望我得到了正确的引语:在申请之前,尝试不使用-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
在脚本中使用sed,或使用Perl脚本:

find . -name *.c -print0 | xargs -0 sed -i.bak -e "s/\#include\s\"\([^\"]+/)\"/\#include\s\"\L\1\"/"
-i、 bak会将文件备份到原始的_file_name.bak,这样您就不必担心会出现问题

这一行将C文件中的所有头文件更改为小写

然后要更改所有文件名:

find . -name *.h -print0 | xargs -0 rename 's/(*)/\L\1/'
这会将所有头文件重命名为小写

这仅适用于linux。如果您使用的是Windows,则可能需要使用Perl或Python脚本来完成上述所有操作

在脚本中使用sed,或使用Perl脚本:

find . -name *.c -print0 | xargs -0 sed -i.bak -e "s/\#include\s\"\([^\"]+/)\"/\#include\s\"\L\1\"/"
-i、 bak会将文件备份到原始的_file_name.bak,这样您就不必担心会出现问题

这一行将C文件中的所有头文件更改为小写

然后要更改所有文件名:

find . -name *.h -print0 | xargs -0 rename 's/(*)/\L\1/'
这会将所有头文件重命名为小写


这仅适用于linux。如果您使用的是Windows,您可能希望对上述内容使用Perl或Python脚本。

这可能适用于GNU-sed:

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

这可能适用于GNU sed:

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

感谢所有关于小写文件名和包含字符串的详细信息。 然而,我最初的问题是执行文字替换

下面是满足我要求的基本命令和sed脚本

ls*.h*.h | sed-es/\[^\r\n]*/s\/\\\包括\\\s\\\\\\ 1\\\\\\\\\\\\\\\\/gi/g>>sedcmd.txt

ls*.h*.h创建文件列表,一次一行 将此列表传送到sed。 搜索整行,这是一个文件名。将整条线放入第1组。s/\^\r\n]*\/ 用字符串s/\\include\s\/\1/gi替换整行文件名 字符串include位于组1中。gi中的i表示执行不区分大小写的搜索。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

感谢所有关于小写文件名和包含字符串的详细信息。 然而,我最初的问题是执行文字替换

下面是满足我要求的基本命令和sed脚本

ls*.h*.h | sed-es/\[^\r\n]*/s\/\\\包括\\\s\\\\\\ 1\\\\\\\\\\\\\\\\/gi/g>>sedcmd.txt

ls*.h*.h创建文件列表,一次一行 将此列表传送到sed。 搜索整行,这是一个文件名。将整条线放入第1组。s/\^\r\n]*\/ 用字符串s/\\include\s\/\1/gi替换整行文件名 字符串include位于组1中。gi中的i表示执行不区分大小写的搜索。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

对于包含斜杠的路径名,我的解决方案不会失败。希望您的头路径中不包含%符号

它的速度也快了几个数量级,在几百个文件上大约需要13秒,而不是等待几分钟

!/bin/bash shopt-s globstar failglob nocaseglob 您应该推送到include路径根。 pushd包含/路径/根 标题=***/.h 邻苯二胺 headers+=*.h我的代码库在项目根目录中有一些额外的头文件。 echo${headers[*]}头 将每个更换件与其他部件分开; 正则表达式= 用于${headers[@]}中的头;做 正则表达式+=';s%包含“$header”%include“$header”%gI” 完成 regex=${regex:1} 找到-f型-iname'*.cpp'-print0|\ xargs-0 sed-i$regex 让sed直接运行要快得多
每个文件有多个ce-分开的正则表达式。

对于包含斜杠的路径名,我的解决方案不会失败。希望您的头路径中不包含%符号

它的速度也快了几个数量级,在几百个文件上大约需要13秒,而不是等待几分钟

!/bin/bash shopt-s globstar failglob nocaseglob 您应该推送到include路径根。 pushd包含/路径/根 标题=***/.h 邻苯二胺 headers+=*.h我的代码库在项目根目录中有一些额外的头文件。 echo${headers[*]}头 将每个更换件与其他部件分开; 正则表达式= 用于${headers[@]}中的头;做 正则表达式+=';s%包含“$header”%include“$header”%gI” 完成 regex=${regex:1} 找到-f型-iname'*.cpp'-print0|\ xargs-0 sed-i$regex

使sed在多个文件中每个文件只运行一次要快得多-分开的正则表达式。

或者考虑修复源树以符合C语言约定。使用脚本生成mv FILE2.H FILE2.H。杰莫。祝你好运。是的,把所有的文件放低是最终的目标,但是一步一步。或者考虑修复你的源树以符合C语言的约定。使用脚本生成mv FILE2.H FILE2.H。杰莫。祝你好运。是的,将所有文件小写是最终目标,但一步一个脚印。在外部使用双引号进行插值。@texasbruce恐怕我不知道你这里所说的插值是什么意思。我可以在sed命令的任何地方使用双引号,但是我必须在替换中转义双引号。@texasbruce啊,是的,但是引号不是强制性的,是吗?测试class='FOO';echo$test'BAR'工作正常…如果执行“$variable”,则不会发生变量插值。同样在单引号字符串中,也应该转义单引号。@texasbruce是的,但在我的回答中,插值发生在单引号之外。我将它们完全打断以插入变量,然后重新开始。考虑:test='BAR';echo'foo'$test'baz.在插值时在外部使用双引号。@texasbruce恐怕我不知道你这里的插值是什么意思。我可以在sed命令的任何地方使用双引号,但是我必须在替换中转义双引号。@texasbruce啊,是的,但是引号不是强制性的,是吗?测试class='FOO';echo$test'BAR'工作正常…如果执行“$variable”,则不会发生变量插值。同样在单引号字符串中,也应该转义单引号。@texasbruce是的,但在我的回答中,插值发生在单引号之外。我将它们完全打断以插入变量,然后重新开始。考虑:test='BAR';echo'foo'$test'baz.这不是一个完整的解决方案,因为必须更改*.h文件中的include文件以及*.cpp。这不是一个完整的解决方案,因为必须更改*.h文件中的include文件以及*.cpp。我喜欢将所有文件更改为小写的想法,但由于源代码处于版本控制下,许多文件名都会更改,从版本控制的角度来看,这会导致一些文件被删除,而另一些文件是新的。需要让版本控制知道文件重命名。@KeithSmith:这可以使用与重命名相同的方法来完成。例如,在performe中,它将是p4编辑,然后是p4move@MSalters-是的。SVN有SVN移动。Git有Git mv。Mercurial有一个新名字。由于我不经常重命名文件,我担心的是重命名文件时会丢失历史记录。@KeithSmith:任何合适的存储库都会在重命名时保留文件历史记录。我最后使用了follow命令。找到-名称*.c-print0 | xargs-0 sed-i.bak-e s/include\s\[^\]+/\/include\s\\L\1\/用于我的bash和sed变体。我喜欢将所有文件更改为小写的想法,但由于源代码处于版本控制之下,许多文件名都发生了更改,导致一些文件被删除,而另一些文件是新的,从版本控制的角度来看。需要让版本控制知道文件重命名。@KeithSmith:这可以使用与重命名相同的方法来完成。例如,在performe中,它将是p4编辑,然后是p4move@MSalters-是的。SVN有SVN移动。Git有Git mv。Mercurial有一个新名字。由于我不经常重命名文件,我担心的是重命名文件时会丢失历史记录。@KeithSmith:任何合适的存储库都会在重命名时保留文件历史记录。我最后使用了follow命令。找到-名称*.c-print0 | xargs-0sed-i.bak-es/include\s\[^\]+/\/include\s\\L\1\/用于我的bash和sed变体。