Найти текст в файлах и переименовать файлы в пакетном режиме

Найти текст в файлах и переименовать файлы в пакетном режиме

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

например, у меня есть папка с файлами file1, file2, file3

content in file1: sw_part = "ABC-DEF.GHJ";
content in file2: sw_part = "ABC-123.XYZ";
content in file3: sw_part = "ABCDE-FGHJ.KLMN";

Результат должен быть:

file1 renamed to ABC-DEF.GHJ
file2 renamed to ABC-123.XYZ
file3 renamed to ABCDE-FGHJ.KLMN

Вот что я сделал:

for /F "tokens=2 delims==" %%a in ('findstr /I "sw_part" file1') do set "swpart=%%a"  
echo sw part is: %swpart%   
copy file1 "%swpart%"

Это работает нормально, но работает только для заданного файла (я не могу заставить это работать с циклом), а также переименовывает файл с помощью;в конце. Есть помощь?

Это нужно сделать в пакетном режиме. PowerShell тоже подойдет.

Спасибо

решение1

Следующий скрипт сделает то, что вам нужно.

cd C:\temp\swpart

$files = [System.Collections.ArrayList]@()

select-string -Path "*.*" -Pattern "sw_part" | ForEach-Object {
   
    $old_filename = $_.Filename

    $new_filename = $_.line -replace "^.*sw_part = ""","" -replace """.*$",""


    # put everything in array, so the files get closed and can be renamed later.
    $null = $files.Add(@{"old"=$old_filename;"new"=$new_filename})

}

$files |ForEach-Object{
    $old_filename = $_.old
    $new_filename = $_.new

    rename-item $old_filename $new_filename -Force
}


Обязательно измените первую строку на путь к файлам.

Если по какой-то причине не все файлы переименованы, запустите скрипт еще раз. Тогда файл все еще использовался.

решение2

  • С помощью PowerShell вы также можете сделать это, используя всего две строки:
ls 'F:\2020-SU\Q1605996\*.txt'|%{$new=(cat $_.FullName).split('\"*\"')[-2];ren $_.FullName -new $new -force}
  • Без использования псевдонимов:
Get-ChildItem 'F:\2020-SU\Q1605996\*.txt' | ForEach {
      $new=(Get-Content $_.FullName).split('\"*\"')[-2]
      Rename-Item $_.FullName -new $new -force
     }


  • Вы также можете сделать это с помощью cmd всего в одну строку:

В командной строке:

for /f tokens^=1-3delims^=^:^"^" %a in ('findstr . *.txt')do @ren "%~fa" "%~c"

В файле bat/cmd:

@echo off 

cd /d "C:\Path\To\Your\Folder"
for /f tokens^=1-3delims^=:^"^" %%a in ('findstr . *.txt')do @ren "%%~fa" "%%~c"

Findstrкоманда и вывод

>F:\Q1605996>findstr . *.txt
file1.txt:sw_part = "ABC-DEF.GHJ";
file2.txt:sw_part = "ABC-123.XYZ";
file3.txt:sw_part = "ABCDE-FGHJ.KLMN";
file4.txt:sw_part = "ABCDE-FGHJ.KXMN";more test/strings
file5.txt:this is a test; sw_part = "fea.geow.eaf.gae"; this is another test;

Forмеханика циклической команды

set yours delimiters : + " + "   ==>>    delims^=:^"^" 
set yours tokens "1" - "3"             ==>>    tokens^=1-3
              :        =                  ;
     token = 1:token =2=         token = 3;
     file1.txt:sw_part = "ABC-DEF.GHJ"    ;
     file2.txt:sw_part = "ABC-123.XYZ"    ;
     file3.txt:sw_part = "ABCDE-FGHJ.KLMN";
     file4.txt:sw_part = "ABCDE-FGHJ.KXMN";more test/strings
    |         |          |               |
ren    "%f~a"                  "%~c"
ren "F:\Q1605996\file1.txt"  "ABC-DEF.GHJ"
ren "F:\Q1605996\file2.txt"  "ABC-123.XYZ"
ren "F:\Q1605996\file3.txt"  "ABCDE-FGHJ.KLMN"
ren "F:\Q1605996\file4.txt"  "ABCDE-FGHJ.KXMN"


rem :: The same in file5.txt 
     file5.txt:this is a test;sw_part = "fea.geow.eaf.gae"; this is another test;
    |         |                         |                |
ren    "%f~a"                                 "%~c"
ren "F:\Q1605996\file5.txt"             "fea.geow.eaf.gae"



Дополнительные ресурсы PowerShell:

Дополнительные ресурсы cmd/batch:

Связанный контент