Я создал несколько тестовых файлов, содержащих ваши образцы:
> Select-String file*.cpp -patt 'hpp'
File1.cpp:1:#include <a0/b/c/d/HeaderFile1.hpp>
File2.cpp:1:#include <a1/b/c/d/HeaderFile2.hpp>
File3.cpp:1:#include <a2/b/c/d/HeaderFile3.hpp>
File4.cpp:1:#include <a3/b/c/d/HeaderFile4.hpp>
File5.cpp:1:#include <a4/b/c/d/HeaderFile5.hpp>
File6.cpp:1:#include <a5/b/c/d/HeaderFile6.hpp>
В следующем сценарии используется объяснение RegEx в прямом эфире на RegEx101 и ниже статического.
## Q:\Test\2018\06\09\SO_50777494.ps1
## the following RegEx usees a positive lookbehind and a
## capture group for the filename.
[RegEx]$Search = '(?<=#include ).*\/([^>]+)>'
$Replace = '"$1"'
ForEach ($File in (Get-ChildItem -Path '.\File*.cpp' -Recurse -File)) {
(Get-Content $File) -Replace $Search,$Replace |
Set-Content $File
}
Пример вывода строки выбора после замены:
> sls file*.cpp -patt 'hpp'
File1.cpp:1:#include "HeaderFile1.hpp"
File2.cpp:1:#include "HeaderFile2.hpp"
File3.cpp:1:#include "HeaderFile3.hpp"
File4.cpp:1:#include "HeaderFile4.hpp"
File5.cpp:1:#include "HeaderFile5.hpp"
File6.cpp:1:#include "HeaderFile6.hpp"
Объяснение RegEx:
(?<=#include ).*\/([^>]+)>
Positive Lookbehind (?<=#include )
Assert that the Regex below matches
#include matches the characters #include literally
.*
. matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times,
as many times as possible, giving back as needed (greedy)
\/ matches the character / literally (case sensitive)
1st Capturing Group ([^>]+)
Match a single character not present in the list below [^>]+
+ Quantifier — Matches between one and unlimited times,
as many times as possible, giving back as needed (greedy)
> matches the character > literally (case sensitive)