Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Удалить строку с ключевым набором символов во всех файлах в папке и всех подпапках. (http://forum.oszone.net/showthread.php?t=340963)

BerryMOR 18-06-2019 09:57 2876005

Удалить строку с ключевым набором символов во всех файлах в папке и всех подпапках.
 
Здравствуйте, очень нужна помощь в решении следующей задачи!

Есть папка .\temp в которой находятся файлы и подпапки то же с файлами.
Нужно найти htm- и js-файлы с ключевым набором символов, например - "_temp" и удалить строки, в которых он встречается.
При чем, как в папке, где находится мой батник, так и во всех подпапках.
Я тут набросал, но к сожалению не работает -

Код:

SetLocal EnableExtensions
 
:: маска htm-файлов
set mask_htm=*.htm
:: маска js-файлов
set mask_js=*.js
:: перфикс для новых файлов
set prefix=p_tmp_pref_
:: ключевое слово, которое необходимо удалить.
set StringForDelete=_temp

:: Создание новых файлов с уже вырезанными ключевыми словами
For  /F "delims=" %%a in ('dir /b "%cd%\%mask_htm%"') do ( :: if NOT %%a == %NameBat% (
        < "%%a" find /I /V "%StringForDelete%" > "%cd%\%prefix%%%a"
)
For  /F "delims=" %%a in ('dir /b "%cd%\%mask_js%"') do ( :: if NOT %%a == %NameBat% (
        < "%%a" find /I /V "%StringForDelete%" > "%cd%\%prefix%%%a"
)

:: Удаление файлов, в которых были найдены ключевые слова.
For /F "delims=" %%b in ('dir /b "%cd%\%mask_htm%" ^| find /i /v "%prefix%"') do (
            del /q "%%b"
)
For /F "delims=" %%b in ('dir /b "%cd%\%mask_js%" ^| find /i /v "%prefix%"') do (
            del /q "%%b"
)

:: Переименование файлов с вырезанными ключевыми словами.
For /f %%d in ('dir /b "%cd%\%prefix%*"') do (
        for /f "tokens=* delims=\%prefix%" %%n in ('echo %%d') do (
                ren "%%d" "%%n"
  )
)


alpap 19-06-2019 08:45 2876083

Цитата:

Цитата BerryMOR
и удалить строки, в которых он встречается »

вы, вероятно, даже не представляете насколько непросто это для cmd. Такую задачу лучше решать на подходящем для этого языке.
еще может быть что я неправильно понимаю задачу или напротив, вы неправильно ее формулируете, возможно условие должно звучать так:
Найти все файлы ... в имени которых встречается "_temp" и переименовать их, вырезав искомое сочетание. Но в таком случае надо предусмотреть как поступить в случае совпадения имен после вырезания искомой вставки.

BerryMOR 19-06-2019 11:07 2876091

Не представлял, когда начинал это делать. Сейчас уже представляю. Задача мной сформулирована корректно.
Но надеялся, что может найдется гуру, кто предложит решение. Я искал-искал, но не смог.
Если нет, то наверное сделаю консольку на с# каком-нибудь.
Жаль конечно потраченного времени. Но что ж поделаешь, если изначально не смог правильно оценить возможности инструментария.
Будет наука.

YuS_2 19-06-2019 18:05 2876143

Цитата:

Цитата BerryMOR
искал-искал, но не смог. »

не там искали. Надо было в powershell посмотреть, для него это вполне просто. Если устроит - решение можно и подсказать.

megaloman 19-06-2019 18:33 2876145

BerryMOR,
Если задача Вами сформулирована корректно и мной правильно понята, то вот vbs
Код:

RegExp = ".*\.htm|.*\.js"
Text = "_temp"
BoxIn = "Z:\Box_In\temp"

'  BoxIn = "temp"              ' Если скрипт забросить в папку где подпапка temp
'  BoxIn = Replace(WScript.ScriptFullName, WScript.ScriptName, "") + BoxIn

Set Mask = CreateObject("VBScript.RegExp")
Mask.Pattern = RegExp
Mask.IgnoreCase = True
Mask.Global = True

j = 0
Call AllFold(BoxIn, Mask, Text, CreateObject("Scripting.FileSystemObject"), j)
MsgBox "Обработано " + CStr(j) + " файлов"

Sub AllFold(inDir, Msk, Txt, FO, j)    ' ---------------------------------------------
With FO
    Set Fold = .GetFolder(inDir)
    Set Files = Fold.Files

    For Each iFile In Files      ' Цикл по файлам в папке
        If Msk.Test(iFile.Name) Then
        If iFile.Size > 0 Then
            Set Fin = .OpenTextFile(iFile, 1, False)
            Tall = Fin.ReadAll
            Fin.Close
           
            Tall = RTrim(Tall)
            If Right(Tall, 2) = vbCrLf Then Tall = Mid(Tall, 1, Len(Tall) - 2)
           
            If InStr(1, Tall, Txt) > 0 Then
           
                Tall = Split(Tall, vbCrLf)
                Set Fout = .OpenTextFile(iFile, 2, True)
           
                For Each SS In Tall
                    If InStr(1, SS, Txt) = 0 Then Fout.WriteLine SS
                Next
           
                Fout.Close
                Set Tall = Nothing
                                                '''''''''''''' MsgBox iFile
                j = j + 1
            End If
        End If
        End If
    Next
    Set F = .GetFolder(inDir)
    Set SubF = F.SubFolders
End With

For Each Folder In SubF
    Call AllFold(Folder, Msk, Txt, FO, j)
Next

End Sub

То же, но удаление строк организовано через Replace,
страшновато, надо аккуратно написать регулярку для поиска
Код:

RegExp = ".*\.htm|.*\.js"
Text = vbCrLf + ".*?_temp.*?" + vbCrLf
BoxIn = "Z:\Box_In\temp"

'  BoxIn = "temp"              ' Если скрипт забросить в папку где подпапка temp
'  BoxIn = Replace(WScript.ScriptFullName, WScript.ScriptName, "") + BoxIn

Set Mask = CreateObject("VBScript.RegExp")
Mask.Pattern = RegExp
Mask.IgnoreCase = True
Mask.Global = True

Set RegText = CreateObject("VBScript.RegExp")
RegText.Pattern =Text
RegText.IgnoreCase = True
RegText.Global = True

j = 0
Call AllFold(BoxIn, Mask, RegText, CreateObject("Scripting.FileSystemObject"), j)
MsgBox "Обработано " + CStr(j) + " файлов"

Sub AllFold(inDir, Msk, Txt, FO, j)    ' ---------------------------------------------
With FO
    Set Fold = .GetFolder(inDir)
    Set Files = Fold.Files

    For Each iFile In Files      ' Цикл по файлам в папке
        If Msk.Test(iFile.Name) Then
        If iFile.Size > 0 Then
            Set Fin = .OpenTextFile(iFile, 1, False)
            Tall = Fin.ReadAll
            Fin.Close
               
            Tall = vbCrLf + Tall + vbCrLf
            LL1 = Len(Tall)
            Tall = Txt.Replace(Tall, vbCrLf)
            LL2 = Len(Tall)
            If LL1 <> LL2 Then
                Set Fout = .OpenTextFile(iFile, 2, True)
                Fout.Write Mid(Tall, 3, LL2 - 4)
                Fout.Close
                Set Tall = Nothing
                                                '''''''''''''' MsgBox iFile
                j = j + 1
            End If
        End If
        End If
    Next
    Set F = .GetFolder(inDir)
    Set SubF = F.SubFolders
End With

For Each Folder In SubF
    Call AllFold(Folder, Msk, Txt, FO, j)
Next

End Sub


megaloman 20-06-2019 14:48 2876228

Цитата:

Цитата alpap
вы, вероятно, даже не представляете насколько непросто это для cmd »

CMD
Код:

@Echo Off
cls
        Set "BoxIn=Z:\Box_In\Temp"
        Set "Mask="*.htm" "*.js""
        Set "Text=_temp"

        Pushd "%BoxIn%"
        FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D /S %Mask%`) DO (
                Echo "%%f"
                >nul 2>&1 Find "%Text%" "%%f" && (
                        >"%%f.tmp" FindStr /V "%Text%" "%%f"
                        >nul Move /Y "%%f.tmp" "%%f"
                )
        )
        Popd
Pause
Exit /B

Цитата:

Цитата Артур Блох+Мэрфи
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы. »

В зависимости от символов в файлах, скрипт то ли отработает корректно, то ли нет. Зато просто.

alpap 20-06-2019 18:26 2876248

megaloman, если в строках будут разные выкрутасы и вдобавок неудобная кодировка, то тут и начнется то о чем я говорил иначе просто повезло.


Время: 07:53.

Время: 07:53.
© OSzone.net 2001-