PDA

Показать полную графическую версию : [решено] Заменить ссылки в txt файле, найдя одинаковые номера


Alexander_88
14-12-2023, 15:17
Здравствуйте, подскажите как сделать такое на 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
Нужно проверить, сравнить 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
Нужно проверить, сравнить 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
А можно сделать, чтобы определяло именно по номеру файла, игнорируя имя и расширение? »

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

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


если мне нужно таким образом проверить 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
Как-то так, опять же проверьте »
Спасибо, завтра обязательно проверю, сегодня уже нет возможности..


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

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

Foreigner
14-12-2023, 21:46
могу их через запятую перечислить? »

Да, можно.

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

megaloman
16-12-2023, 18:13
@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
megaloman, спасибо, попробовал, теперь расширение и имя игнорирует как и нужно, только дольше обрабатывает :) 1 файл для теста попробовал (800 ссылок), и почему то сбивает сортировку..
все выводится не по порядку по номерам.. к примеру первые 5 строк с номерами файлов:

0625
0002
0628
0004
0102

Alexander_88
17-12-2023, 17:58
Foreigner, попробовал второй вариант, но как будто бы ничего не поменялось.. »
заметил, что строк стало меньше почему то

megaloman
18-12-2023, 17:40
Alexander_88, чтобы быстро и с сортировкой по возрастанию - vbsOption 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
а куда выходит результирующий файл? или он заменяется?

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
есть несколько 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
megaloman, спасибо, все получилось, заменяет 800 ссылок очень быстро :)




© OSzone.net 2001-2012