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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Заменить ссылки в txt файле, найдя одинаковые номера (http://forum.oszone.net/showthread.php?t=354684)

Alexander_88 14-12-2023 15:17 3021524

Заменить ссылки в txt файле, найдя одинаковые номера
 
Здравствуйте, подскажите как сделать такое на powershell или bath ?

есть несколько txt файлов.. в каждом txt ссылки одного из нескольких типов..

пример одного из типов:

Код:

https://google.com/file/6c616b50641a8/0001start.mp4
https://google.com/file/f0bafe33ee86d/0002start.mp4
https://google.com/file/82c4d96027879/0003start.mp4
https://google.com/file/2ca5c2ed414b6/0004start.mp4
https://google.com/file/8e616f8c54ce8/0005start.mp4
https://google.com/file/484651ad8773a/0006start.mp4
https://google.com/file/a0abb050c39f5/0007start.mp4
https://google.com/file/e93fb78dbcfcf/0008start.mp4
https://google.com/file/613bf9cc27632/0009start.mp4
https://google.com/file/e95ba702a2557/0010start.mp4
https://google.com/file/c7f25a80f361d/0011start.mp4
https://google.com/file/deletelink/0012start.mp4
https://google.com/file/bd95035d50f7a/0013start.mp4
https://google.com/file/deletelink/0014start.mp4
https://google.com/file/c5b0e8bc53652/0015start.mp4
https://google.com/file/deletelink/0016start.mp4
https://google.com/file/2ca4038062eb9/0017start.mp4
https://google.com/file/deletelink/0018start.mp4
https://google.com/file/976582ec7e383/0019start.mp4
https://google.com/file/20ab0d8a2856c/0020start.mp4
https://google.com/file/deletelink/0021start.mp4
https://google.com/file/df3b1c7694b27/0022start.mp4
https://google.com/file/deletelink/0023start.mp4
https://google.com/file/deletelink/0024start.mp4
https://google.com/file/9ce184ff0b163/0025start.mp4
https://google.com/file/es5gscfcf/0008start.mp4
https://google.com/file/c5bfgju3652/0015start.mp4
https://google.com/file/dwtgink/0021start.mp4

бывают txt с другими типами.. отличие в основном в имени файла, расширения разные, есть txt где в имени файла присутствует знак земли _ (примеры типов имен файлов.. 0024start.mp4, start0024.mp4, 0024start_m.jpg, start0024_m.jpg (буква после земли может быть другая).
Но как я говорил в одном txt файлы только какого - нибудь одного типа, необходимо либо несколько скриптов под разные типы файлов, либо один универсальный (если это возможно).
Теперь к тому, что должен делать скрипт :)

в каждом txt файле список ссылок, в конце которых есть имя файла... в составе имени файла обязательно есть номер, состоящий из 4ех цифр... номер этих цифр идет по порядку, начиная с 0001 (0001 - первая ссылка, 0002 - вторая ссылка, 0003 третья ссылка и т.д.). В какой то момент порядок нарушается, и идут ссылки, которые должны заменить тех, что выше (находить тех, которых заменить нужно по номеру), ссылка должна замениться полностью.

Другими словами нужно выполнить замену ссылок со старых на новые.. старые выше, новые ниже, определять по 4ех значному номеру в имени файла. За место старых ссылок должны встать новые, а новые со своих мест (снизу) удалиться. Дубликатов в новых ссылках не будет, номера у них будут разные.. такие же номера 100% будут в старых ссылках. txt файлы должны заменится на новые после применения скрипта. Из примера выше, после применения скрипта, txt файл должен стать таким..


Код:

https://google.com/file/6c616b50641a8/0001start.mp4
https://google.com/file/f0bafe33ee86d/0002start.mp4
https://google.com/file/82c4d96027879/0003start.mp4
https://google.com/file/2ca5c2ed414b6/0004start.mp4
https://google.com/file/8e616f8c54ce8/0005start.mp4
https://google.com/file/484651ad8773a/0006start.mp4
https://google.com/file/a0abb050c39f5/0007start.mp4
https://google.com/file/es5gscfcf/0008start.mp4
https://google.com/file/613bf9cc27632/0009start.mp4
https://google.com/file/e95ba702a2557/0010start.mp4
https://google.com/file/c7f25a80f361d/0011start.mp4
https://google.com/file/deletelink/0012start.mp4
https://google.com/file/bd95035d50f7a/0013start.mp4
https://google.com/file/deletelink/0014start.mp4
https://google.com/file/c5bfgju3652/0015start.mp4
https://google.com/file/deletelink/0016start.mp4
https://google.com/file/2ca4038062eb9/0017start.mp4
https://google.com/file/deletelink/0018start.mp4
https://google.com/file/976582ec7e383/0019start.mp4
https://google.com/file/20ab0d8a2856c/0020start.mp4
https://google.com/file/dwtgink/0021start.mp4
https://google.com/file/df3b1c7694b27/0022start.mp4
https://google.com/file/deletelink/0023start.mp4
https://google.com/file/deletelink/0024start.mp4
https://google.com/file/9ce184ff0b163/0025start.mp4

т.е. осталось 25 ссылок, идущих по порядку по номеру, остальные 3, которые были ниже, заменили собой тех, которые были выше, найдя их по номеру :)

Foreigner 14-12-2023 17:29 3021529

Нужно проверить, сравнить list-in.txt и list-out.txt, но вроде все корректно

Код:

[uri[]] $urls = Get-Content list-in.txt
$urls | Group-Object { $_.Segments[-1] } | Foreach-Object { $_.Group[-1].OriginalString } | Set-Content list-out.txt


Alexander_88 14-12-2023 19:49 3021533

Цитата:

Цитата Foreigner
Нужно проверить, сравнить list-in.txt и list-out.txt, но вроде все корректно »

Спасибо, проверил через онлайн сервис сравнения двух тхт, все нормально.. А можно сделать, чтобы определяло именно по номеру файла, игнорируя имя и расширение? (ссылку также заменять полностью на новую).
и вопросик. если мне нужно таким образом проверить 50 txt файлов, и заменить оригиналы, на то, что результировал скрипт, нужно так делать?

Код:

[uri[]] $urls = Get-Content list-in.txt
$urls | Group-Object { $_.Segments[-1] } | Foreach-Object { $_.Group[-1].OriginalString } | Set-Content list-in.txt

и перекопировать этот код 50 раз изменяя имена файлов? ничего не нарушится при этом?

Foreigner 14-12-2023 21:28 3021536

Цитата:

Цитата Alexander_88
А можно сделать, чтобы определяло именно по номеру файла, игнорируя имя и расширение? »

Как-то так, опять же проверьте
Код:

[uri[]] $urls = gc list-in.txt
$urls | group-object { $_.Segments[-1] -replace '(?<=\d4).+' } | % { $_.Group[-1].OriginalString } | sc list-out.txt

Цитата:

Цитата Alexander_88
если мне нужно таким образом проверить 50 txt файлов, и заменить оригиналы, на то, что результировал скрипт, нужно так делать? »

Можно, нужно завернуть в цикл:

Код:

$files = dir *.txt                    # Ваши *.txt файлы
foreach ($file in $files)
{
    [uri[]] $urls = Get-Content $file
    $urls | Group-Object { $_.Segments[-1] -replace '(?<=\d4).+' } | Foreach-Object {
        $_.Group[-1].OriginalString
    } | Set-Content $file            # перезаписывается исходный !!
}


Alexander_88 14-12-2023 21:37 3021537

Цитата:

Цитата Foreigner
Как-то так, опять же проверьте »

Спасибо, завтра обязательно проверю, сегодня уже нет возможности..


Цитата:

Цитата Foreigner
Можно, нужно завернуть в цикл: »

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

Foreigner 14-12-2023 21:46 3021538

Цитата:

Цитата Alexander_88
могу их через запятую перечислить? »

Да, можно.

Alexander_88 15-12-2023 21:21 3021575

Foreigner, попробовал второй вариант, но как будто бы ничего не поменялось.. также зависит от имени и расширения а не только от номера.. т.е. заменяет, если полностью совпадает имя файла (номер имя и расширение) :dont-know

megaloman 16-12-2023 18:13 3021598

Код:

@Echo Off &Cls
>nul Chcp 1251
SetLocal EnableDelayedExpansion
        Call :MyDir "Z:\Box_In\*.txt" "Z:\Box_Out"
        Call :MyDir "Z:\Soft_In\*.txt" "Z:\Soft_In"
Pause
Exit /B

:MyDir
        FOR %%f In (%1) DO Call :Replace "%%f" %2
Exit /B

:Replace
        Echo %1 -^> %2
        For /F "usebackq tokens=3 delims=:" %%i In (`2^>nul Find /C ":" %1`) Do Set /A N=%%i
        If %N% EQU 0 (Exit /B 1)
        Set /A N+=10000
        >"%~2\%~nx1.tmp" (For /L %%i In (10001,1,%N%) Do (
                Set /A M=%%i
                Set "M=/.*!M:~1!.*\..*"
                Set "SS="
                For /F "usebackq delims=" %%s In (`2^>nul FindStr /R /E /C:"!M!" %1`) Do Set "SS=%%s"
                If Not "!SS!"=="" (Echo !SS!)
        ))
        >nul Move /Y "%~2\%~nx1.tmp" "%~2\%~nx1"
Exit /B

Скрипт просматривает файлы по указанной маске в указанной папке и помещает результаты в другую папку.
Папки могут и совпадать
A если пути файлов разные для каждого пишем свой Call :MyDir

Alexander_88 17-12-2023 17:02 3021620

megaloman, спасибо, попробовал, теперь расширение и имя игнорирует как и нужно, только дольше обрабатывает :) 1 файл для теста попробовал (800 ссылок), и почему то сбивает сортировку..
все выводится не по порядку по номерам.. к примеру первые 5 строк с номерами файлов:

0625
0002
0628
0004
0102

Alexander_88 17-12-2023 17:58 3021622

Цитата:

Цитата Alexander_88
Foreigner, попробовал второй вариант, но как будто бы ничего не поменялось.. »

заметил, что строк стало меньше почему то

megaloman 18-12-2023 17:40 3021676

Вложений: 1
Alexander_88, чтобы быстро и с сортировкой по возрастанию - vbs
Код:

Option Explicit

Dim BoxIn, AllFol
AllFol = Array("Z:\Box_In", _
            "Z:\Soft_In")

Dim FSO, App, Fol, Itm, File, S, SS, Reg, num, i, Max
Set FSO = CreateObject("Scripting.FileSystemObject")
Set App = CreateObject("Shell.Application")
Set Reg = CreateObject("VBScript.RegExp"): Reg.Global = True

For Each BoxIn In AllFol
    Set Fol = App.Namespace(BoxIn)
    Set Itm = Fol.Items()
    Itm.Filter 64 + 128, "*.txt"

    ReDim AllOut(9999)
    For Each File In Itm
        File = BoxIn + "\" + File.Name
        With FSO.OpenTextFile(File, 1, False)
            Max = 0
            Do While Not .AtEndOfStream
                SS = .ReadLine
                If SS <> Empty Then
                    S = Split(SS, "/")
                                i = UBound(S)
                    num = FSO.GetBaseName(S(i))
                    If Reg.Test(num) Then
                        Reg.Pattern = "\D"
                        num = CLng(Reg.Replace(num, ""))
                        If num <= 9999 Then
                            If Max < num Then Max = num
                            AllOut(num) = SS
                        End If
                    End If
                End If
            Loop
            .Close
        End With
       
        With FSO.OpenTextFile(File, 2, True)
            For i = 1 To Max
                If AllOut(i) <> Empty Then .WriteLine (AllOut(i))
            Next
            .Close
        End With
    Next
Next

В прикрепленном файле уберите расширение .txt и пропишите пути к своим папкам

Alexander_88 19-12-2023 21:47 3021735

а куда выходит результирующий файл? или он заменяется?

Код:

Option Explicit

Dim BoxIn, AllFol
AllFol = Array("C:\Work\CONTENT")
Dim FSO, App, Fol, Itm, File, S, SS, Reg, num, i, Max
Set FSO = CreateObject("Scripting.FileSystemObject")
Set App = CreateObject("Shell.Application")
Set Reg = CreateObject("VBScript.RegExp"): Reg.Global = True

For Each BoxIn In AllFol
    Set Fol = App.Namespace(BoxIn)
    Set Itm = Fol.Items()
    Itm.Filter 64 + 128, "fileslink.txt"

    ReDim AllOut(9999)
    For Each File In Itm
        File = BoxIn + "\" + File.Name
        With FSO.OpenTextFile(File, 1, False)
            Max = 0
            Do While Not .AtEndOfStream
                SS = .ReadLine
                If SS <> Empty Then
                    S = Split(SS, "/")
                                i = UBound(S)
                    num = FSO.GetBaseName(S(i))
                    If Reg.Test(num) Then
                        Reg.Pattern = "\D"
                        num = CLng(Reg.Replace(num, ""))
                        If num <= 9999 Then
                            If Max < num Then Max = num
                            AllOut(num) = SS
                        End If
                    End If
                End If
            Loop
            .Close
        End With
       
        With FSO.OpenTextFile(File, 2, True)
            For i = 1 To Max
                If AllOut(i) <> Empty Then .WriteLine (AllOut(i))
            Next
            .Close
        End With
    Next
Next

что то ничего не происходит, наверное пути не правильно поставил.

megaloman 20-12-2023 07:24 3021749

Вложений: 1
Цитата:

Цитата Alexander_88
есть несколько txt файлов »

Вы жестко забили в фильтре 1 файл fileslink.txt по 1 пути "C:\Work\CONTENT"
Такой файл имеется? Тут архив тестового комплекта. На нём работает.
Вот вариант скрипта с проверкой существования файла(ов)
Код:

Option Explicit

Dim BoxIn, AllFol
AllFol = Array("C:\Work\CONTENT")                  '("Z:\Box_In", "Z:\Soft_In")
Const Mask = "fileslink.txt"                        '"*.txt"

Dim FSO, App, Fol, Itm, File, S, SS, Reg, num, i, Max
Set FSO = CreateObject("Scripting.FileSystemObject")
Set App = CreateObject("Shell.Application")
Set Reg = CreateObject("VBScript.RegExp"): Reg.Global = True

For Each BoxIn In AllFol
    Set Fol = App.Namespace(BoxIn)
    Set Itm = Fol.Items()
    Itm.Filter 64 + 128, Mask
    If Itm.Count <> 0 Then
        ReDim AllOut(9999)
        For Each File In Itm
            File = BoxIn + "\" + File.Name
            With FSO.OpenTextFile(File, 1, False)
                Max = 0
                Do While Not .AtEndOfStream
                    SS = .ReadLine
                    If SS <> Empty Then
                        S = Split(SS, "/")
                        i = UBound(S)
                        num = FSO.GetBaseName(S(i))
                        If Reg.Test(num) Then
                            Reg.Pattern = "\D"
                            num = CLng(Reg.Replace(num, ""))
                            If num <= 9999 Then
                                If Max < num Then Max = num
                                AllOut(num) = SS
                            End If
                        End If
                    End If
                Loop
                .Close
            End With
       
            With FSO.OpenTextFile(File, 2, True)
                For i = 1 To Max
                    If AllOut(i) <> Empty Then .WriteLine (AllOut(i))
                Next
                .Close
            End With
        Next
    Else
        MsgBox "File(s)" + vbCr + BoxIn + "\" + Mask + vbCr + "not found", 16, "Not found"
    End If
Next


Результирующий файл заменяется.
Иное делается "на раз".

Alexander_88 21-12-2023 07:59 3021778

megaloman, спасибо, все получилось, заменяет 800 ссылок очень быстро :)


Время: 23:58.

Время: 23:58.
© OSzone.net 2001-