Компьютерный форум 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=341390)

Patroklos 15-07-2019 15:45 2879892

Как отсортировать файлы?
 
У меня есть фильмы названные следующим образом: Название, год, оценка.
Код:

Hannibal Rising__2007__6.2__.mp4
Hannibal__2001__6.8__.mp4
Manhunter__1986__7.2__.mp4
Red Dragon__2002__7.2__.mp4
The Silence of the Lambs__1991__8.6__.mp4

Каким образом можно отсортировать файлы по году?

megaloman 15-07-2019 18:22 2879918

Patroklos, Как понять "отсортировать"? Что в результате?
Код:

@Echo Off
cls
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"

        FOR /L %%y IN (1900,1,2050) DO (
                Call Set "MMask=%%Mask:????=%%y%%
                FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D "%BoxIn%\%%MMask%%"`) DO (
                        Echo %%f
        ))
Pause
Exit /B


Iska 15-07-2019 19:05 2879924

Patroklos, в Проводнике — стандартными средствами, полагаю, никак. В скрипте WSH — так:
Скрытый текст
Код:

Option Explicit

Const adVarChar  = 200
Const adVarWChar = 202

Dim strSourceFolder

Dim objFSO
Dim objFile

Dim objRegExp
Dim objRecordSet


If WScript.Arguments.Count = 1 Then
        strSourceFolder = WScript.Arguments.Item(0)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FolderExists(strSourceFolder) Then
                Set objRegExp = WScript.CreateObject("VBScript.RegExp")
               
                objRegExp.Pattern = "^.+__(\d{4})__\d\.\d__\.(?:avi|wmv|flv|3gp|webm|ogv|mpg|mpeg|mp4|mkv|m4v)$"
               
                With WScript.CreateObject("ADODB.RecordSet")
                        With .Fields
                                .Append "File name", adVarWChar, 255
                                .Append "Year",      adVarChar,    4
                        End With
                       
                        .Open()
                       
                        For Each objFile In objFSO.GetFolder(strSourceFolder).Files
                                If objRegExp.Test(objFile.Name) Then
                                        .AddNew Array("File name", "Year"), Array(objFile.Name, objRegExp.Execute(objFile.Name).Item(0).Submatches.Item(0))
                                End If
                        Next
                       
                        .Sort = "Year"
                       
                        Do Until .EOF
                                WScript.Echo .Fields.Item("File name")
                                .MoveNext
                        Loop
                       
                        .Close()
                End With
               
                Set objRegExp = Nothing
        Else
                WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
                WScript.Quit 2
        End If
       
        Set objFSO = Nothing
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder>"
        WScript.Quit 1
End If

WScript.Quit 0


На PowerShell должно быть ещё проще — там можно тупо приписать новое свойство к производному классу и отсортировать по нему.

Patroklos 15-07-2019 19:35 2879929

Цитата:

Цитата megaloman
Как понять "отсортировать"? Что в результате? »

Прошу прощения что непонятно написал.
В результате хочу получить список фильмов отсортированный по году. От младшего к старшему.
Код:

Manhunter__1986__7.2__.mp4
The Silence of the Lambs__1991__8.6__.mp4
Hannibal__2001__6.8__.mp4
Red Dragon__2002__7.2__.mp4
Hannibal Rising__2007__6.2__.mp4

Цитата:

Цитата Iska
в Проводнике — стандартными средствами, полагаю, никак. »

Как раз в проводнике это элементарно. mp4 поддерживает теги с которыми проводник хорошо работает.
Но мне удобней накостылить свой лоунчер.
Цитата:

Цитата Iska
WSH »

Ужас. Я с WSH даже шапочно не знаком. Но спасибо, вот и повод познакомиться.

Iska 15-07-2019 19:51 2879932

Цитата:

Цитата Patroklos
Как раз в проводнике это элементарно. mp4 поддерживает теги с которыми проводник хорошо работает. »

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

YuS_2 15-07-2019 20:10 2879936

Цитата:

Цитата Patroklos
В результате хочу получить список фильмов отсортированный по году. »

получить где? плейлист, консоль, файл, файловый менеджер?
powershell
самый простецкий вариант:
Код:

dir *.mp4|sort{$_.basename -replace '.*(\d{4}).*','$1'}

megaloman 15-07-2019 20:19 2879937

В результате хочу получить список фильмов отсортированный по году. От младшего к старшему.
Код:

@Echo Off
cls
>nul chcp 1251
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"
        Set "OutFile=Z:\Box_In\_Reestr.txt"

        >"%OutFile%" (FOR /L %%y IN (1900,1,2050) DO (
                Call Set "MMask=%%Mask:????=%%y%%
                FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D "%BoxIn%\%%MMask%%"`) DO (
                        Echo %%f
        )))
Pause
Exit /B


Patroklos 15-07-2019 20:27 2879938

Цитата:

Цитата Iska
Так тэги — это тэги, про них ничего не было сказано, а у нас же в техзадании — просто часть имени файла. »

Справедливо замечено. Просто я теги рассматривал в первую очередь. Для этого они и придуманы.
Цитата:

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

Консоль. Дальше я уже сам осилю. Надеюсь.
А можно ещё сортировку по оценке?

megaloman, Спасибо большое, всё работает как надо!

YuS_2 15-07-2019 20:45 2879940

Цитата:

Цитата Patroklos
А можно ещё сортировку по оценке? »

по аналогии:
Код:

dir *.mp4|sort {$_.basename -replace '.*_(\d\.\d)_.*','$1'}
Предполагаю следующий вопрос: "А можно ли совместить?"
- Можно :)
Код:

dir *.mp4|sort {$_.basename -replace '.*_(\d\.\d)_.*','$1'},{$_.basename -replace '.*_(\d{4})_.*','$1'}

Patroklos 15-07-2019 21:04 2879943

Супер, спасибо! А как заставить ПоШ искать рекурсивно и при этом писать в консоль только имя и путь?
Я на сайте МС читаю хелп но он не мне не помог.
Я пишу -Recurse у меня в консоли бардак.
Я пишу -Name -Recurse он не желает искать рекурсивно.
Есть возможность совместить -Name и -Recurse ?

YuS_2 15-07-2019 21:11 2879944

Цитата:

Цитата Patroklos
Есть возможность совместить -Name и -Recurse ? »

Код:

(dir *.mp4 -rec|sort {$_.basename -replace '.*_(\d\.\d)_.*','$1'},{$_.basename -replace '.*_(\d{4})_.*','$1'}).name

Patroklos 15-07-2019 21:15 2879945

Отлично. Спасибо!

megaloman 16-07-2019 09:59 2879998

Увы, но так коротко как в пошике, батник так не напишешь.
CMD: год+рейтинг
Код:

@Echo Off
cls
>nul chcp 1251
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"
        Set "OutFile=Z:\Box_In\_Reestr.txt"
       
        Set /A N=10000
        FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D "%BoxIn%\%Mask%"`) DO (
                Set "Name=%%~nf"
                Set /A N+=1
                Call Set "@@%%Name:*__=%%%%N%%=%%f"
        )
        >"%OutFile%" (FOR /F "usebackq tokens=1* delims==" %%a IN (`2^>nul Set "@@"`) DO Echo %%b)
Pause
Exit /B

искать рекурсивно и при этом писать в консоль только имя и путь
Код:

@Echo Off
cls
>nul chcp 1251
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"
        Set "OutFile=Z:\Box_In\_Reestr.txt"
       
        Set /A N=10000
        FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D /S "%BoxIn%\%Mask%"`) DO (
                Set "Name=%%~nf"
                Set /A N+=1
                Call Set @@%%Name:*__="%%%%N%%=%%~nf"  "%%~dpf"
        )
        >"%OutFile%" (FOR /F "usebackq tokens=1* delims==" %%a IN (`2^>nul Set "@@"`) DO Echo %%b)
Pause
Exit /B


Patroklos 16-07-2019 17:52 2880103

megaloman, спасибо большое!

Patroklos 17-07-2019 18:51 2880307

Уважаемый megaloman, к сожалению скрипт который ищет рекурсивно у меня не работает как надо.
Этот скрипт
Код:

@Echo Off
cls
>nul chcp 1251
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"
        Set "OutFile=Z:\Box_In\_Reestr.txt"
       
        Set /A N=10000
        FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D /S "%BoxIn%\%Mask%"`) DO (
                Set "Name=%%~nf"
                Set /A N+=1
                Call Set @@%%Name:*__="%%%%N%%=%%~nf"  "%%~dpf"
        )
        >"%OutFile%" (FOR /F "usebackq tokens=1* delims==" %%a IN (`2^>nul Set "@@"`) DO Echo %%b)
Pause
Exit /B


Пример результата
Код:

Police Academy__1984__6.7__"  "J:\#Films\"
Heat__1995__8.2__"  "J:\#Films\"
The Matrix__1999__8.7__"  "J:\#Films\Matrix\"
The Matrix Revolutions__2003__6.7__"  "J:\#Films\Matrix\"
The Matrix Reloaded__2003__7.2__"  "J:\#Films\Matrix\"
Elysium__2013__6.6__"  "J:\#Films\"


Как видно имя файла впереди пути и нет расширения.
Я к сожалению не разобрался где и что менять.
Буду признателен если вы поможете починить.

Iska 17-07-2019 20:23 2880312

Patroklos, пользуйте PowerShell, это надёжнее.

megaloman 17-07-2019 21:13 2880322

Цитата:

Цитата Patroklos
писать в консоль только имя и путь »

Цитата:

Цитата Patroklos
Как видно имя файла впереди пути и нет расширения. »

Что просили, то и получили.
Если надо полный путь файлов в традиционном виде:
Код:

@Echo Off
cls
>nul chcp 1251
        Set "BoxIn=Z:\Box_In"
        Set "Mask=*__????__?.?__.mp4"
        Set "OutFile=Z:\Box_In\_Reestr.txt"
       
        Set /A N=10000
        FOR /F "usebackq delims=" %%f IN (`2^>nul Dir /B /A:-D /S "%BoxIn%\%Mask%"`) DO (
                Set "Name=%%~nf"
                Set /A N+=1
rem                Call Set @@%%Name:*__=%%%%N%%="%%~nf"  "%%~dpf"
                Call Set @@%%Name:*__=%%%%N%%=%%f
        )
        >"%OutFile%" (FOR /F "usebackq tokens=1* delims==" %%a IN (`2^>nul Set "@@"`) DO Echo %%b)
Pause
Exit /B


YuS_2 18-07-2019 08:46 2880366

Цитата:

Цитата Patroklos
А как заставить ПоШ искать рекурсивно и при этом писать в консоль только имя и путь? »

Кстати, да, не обратил внимание, в отличие от megaloman, что вопрос был про имя и путь... но теперь уже и понятно, что нужен таки абсолютный путь с именем и расширением.
Для powershell, это будет так:
Код:

(dir *.mp4 -rec|sort {$_.basename -replace '.*_(\d\.\d)_.*','$1'},{$_.basename -replace '.*_(\d{4})_.*','$1'}).fullname

Patroklos 19-07-2019 08:03 2880524

Всем спасибо большое! Выручили.


Время: 23:23.

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