如何用sed递归地为目录中的所有文件替换两个模式之间带尖括号的引号?

How to replace quotation marks with angle brackets between two patterns recursively for all file in a directory with sed?

我正在处理的存储库在 non-flat 目录结构中有多个源文件,例如

project
│   main.cpp
│
└───moduleA
    │   A.cpp

所有这些源文件都有类似于

的代码
#include "A.h"

WINDOWS_DISABLE_WARNING
#include "externalA.h"
#include "externalB.h"
WINDOWS_ENABLE_WARNING

// more code

如何使用 sed 递归地替换所有文件的 WINDOWS_DISABLE_WARNING 宏和 WINDOWS_ENABLE_WARNING 宏之间包含的所有引号?

#include "A.h"

WINDOWS_DISABLE_WARNING
#include <externalA.h>
#include <externalB.h>
WINDOWS_ENABLE_WARNING

// more code

我知道如何像 find ./ -type f -exec sed -i 's/oldtext/newtext/' {} \; 一样递归地替换简单的字符串,但我正在努力弄清楚如何用两个模式之间的尖括号替换引号。

我这样做的原因是因为 Visual Studio recently introduced /external:anglebrackets,如果启用此标志,任何包含在尖括号中的 headers 都被视为外部,并且警告即将到来可以通过 /external:W0 将其关闭。这意味着不再有丑陋的宏,如 WINDOWS_DISABLE_WARNING 如果在 Windows 上定义为 __pragma(warning(push,0)),否则为空,通过 CMake 的 target_compile_definitions 和类似的 WINDOWS_ENABLE_WARNING 定义为__pragma(warning(pop)) 如果在 Windows 上,否则为空,通过 CMake 的 target_compile_definitions。由于使用 sed 递归删除宏非常简单,最终代码可以在使用松散编写的 third-party 库并启用新的 /external 标志时变得像下面这样干净。

#include "A.h"

#include <externalA.h>
#include <externalB.h>

// more code

在 sed

中阅读关于 addressing lines
find ... -exec sed -i '/WINDOWS_DISABLE_WARNING/,/WINDOWS_ENABLE_WARNING/ { s/"/</; s/"/>/ }' '{}' +

确保在尝试 -i

之前备份您的文件 (sed -i.bak)(或省略 -i 选项)