Powershell для замены строки во всех файлах внутри папки - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь запустить скрипт powershell, который заменит вхождение строки другой строкой.Я хочу удалить угловые скобки из включения и заменить их на двойные кавычки только с именем файла заголовка, без пути к папке до имени файла заголовка.Пример:

#include <a/b/c/def.hpp>
#include <a/b/c/ddd.hpp> 

до

#include "def.hpp"
#include "ddd.hpp"

Я пробовал это.

(Get-ChildItem -Recurse | Get-Content | Select-String -Pattern "#include <a/b/c/")-replace '#include <a/b/c/(\w+).*/', '#include "'-replace '>','"'

С этим я получаю желаемый результат, но я не могуиспользуйте результат и замените существующую строку в исходном файле.

Заранее спасибо.

Мне нужно запросить до 100 файлов в папке.Пожалуйста, предложите лучший способ сделать это.

    INPUT 
#include <a0/b/c/d/HeaderFile1.hpp>
#include <a1/b/c/d/HeaderFile2.hpp>
#include <a2/b/c/d/HeaderFile3.hpp>
#include <a3/b/c/d/HeaderFile4.hpp>
#include <a4/b/c/d/HeaderFile5.hpp>
#include <a5/b/c/d/HeaderFile6.hpp>   


OUTPUT
#include "HeaderFile1.hpp"
#include "HeaderFile2.hpp"
#include "HeaderFile3.hpp"
#include "HeaderFile4.hpp"
#include "HeaderFile5.hpp"
#include "HeaderFile6.hpp"

Ответы [ 3 ]

0 голосов
/ 09 июня 2018

Вам просто нужно записать новый текст обратно в файл.вот мой способ сделать это:

Get-ChildItem -Recurse -File | ForEach-Object {

    (Get-Content $_).replace('#include <a/b/c/def.hpp>','#include "def.hpp"') | Set-Content $_
}

Редактировать:

Теперь, когда вы объяснили свой вопрос, ясно, что вам нужно использовать регулярное выражение.тот, который опубликовал LotPings, будет работать отличнопоэтому, используя его RegEx, правильный ответ:

Get-ChildItem -Recurse -File | ForEach-Object {

    (Get-Content $_)-replace('(?<=#include ).*\/([^>]+)>','"$1"') | Set-Content $_
}
0 голосов
/ 10 июня 2018

Я создал несколько тестовых файлов, содержащих ваши образцы:

> 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)
0 голосов
/ 09 июня 2018

Редактировать: проверено на предоставленных вами примерах, если формат может отличаться (более глубокий путь, специальные символы в пути и т. Д.), Пожалуйста, проверьте раньше.И иметь резервную копию

Как-то так должно работать:

$items = Get-ChildItem -Recurse
foreach ($i in $items) {
 $newContent = (Get-Content $i) -replace('#include <((\w)+\/)*(\w+\.hpp)>','#include "$3"')
 $newContent | Set-Content $i
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...