Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
2 / 2 / 0
Регистрация: 23.08.2023
Сообщений: 67

Групповое переименование и объединение файлов txt, с алфавитно-числовой сортировкой

16.04.2025, 00:42. Показов 7296. Ответов 90
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте !
Есть много файлов txt , которые нужно объединить в один
В данный момент я делаю это так

PowerShell
1
Get-Content -Path C:\Test2\*.txt | Set-Content -Path C:\Input.txt
Но объединяются они не в том порядке в котором нужно

Мне нужно чтобы файлы объединялись по естественной сортировки алфавитно-числовой
1
2
10
100

Сейчас сортируется
1
10
100
2

Пробовал сначала txt файлы переименовывать со счетчиком в начале имени файла
PowerShell
1
Get-ChildItem -Path C:\Test2\*.txt | Foreach-Object {$i=1} {ren $_ -NewName ("{0:00#} $($_.Basename).txt" -f $i++) }
Но сортировка получается такая же как и при объединении
Пробовал с Sort-Object -Property Name , так тоже не получается
Подскажите пожалуйста как сделать сортировку алфавитно-числовой?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.04.2025, 00:42
Ответы с готовыми решениями:

Групповое переименование файлов через командную строку
Здравствуйте! Мне нужно создать bat-файл со скриптом, который переименует все файлы в папке C:\SEPT...

Групповое переименование файлов средствами PowerShell 2.0
Здравствуйте, при переименовании файлов скрипт отрабатывает не со всеми форматами, выдает ошибку...

Групповое переименование csv-файлов
Приветствую всех и прошу помощи в написании батника. Исходные данные: Имеется множество csv...

90
 Аватар для volodin661
7097 / 2328 / 353
Регистрация: 10.12.2013
Сообщений: 8,051
23.04.2025, 17:31
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от YuS_2 Посмотреть сообщение
в sqlite и сами регэкспы по умолчанию не включены
они включены в поставку. В ту, которая суть один исполняемый файл sqlite3.exe

PowerShell
1
scoop install sqlite
a extensions там, понятное дело, нет

Добавлено через 2 минуты
В чем тут заключается политика дать/недать - непонятно, долгое время, ведь, и самих регекспов не было,
но лет 5 назад включили.

Добавлено через 2 часа 44 минуты
решение переделать командлет в приём параметров по трубе подорвало мою веру в добро и в собственное осмысленное существование.

Реально об'явить параметр как трубный, а если нет трубы, то как позиционный ?
Как это делается ? Есть здесь самаритяне ? ( не в смысле уроженцев Самары, а в смысле доброприносящих )
0
Любознательный
 Аватар для YuS_2
7407 / 2260 / 361
Регистрация: 10.03.2016
Сообщений: 5,216
23.04.2025, 18:38
Цитата Сообщение от volodin661 Посмотреть сообщение
чем тут заключается политика дать/недать - непонятно, долгое время, ведь, и самих регекспов не было,
но лет 5 назад включили.
по голове им надо было стукнуть, сразу бы всё появилось

Цитата Сообщение от volodin661 Посмотреть сообщение
Реально об'явить параметр как трубный, а если нет трубы, то как позиционный ?
ну, дык это же аргументами параметров функций настраивается и для командлетов аналогично
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Test{
    # по умолчанию тут $true и можно даже не указывать,
    # а если раскомментировать, то позиционный параметр не будет работать:
    #[CmdletBinding(PositionalBinding=$false)] 
    param (
        [Parameter(Mandatory=$false,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName)]
        [string[]]$param
    )
    if($param){
        write-host $param - есть контакт! -for green
    } else {
        write-host нет контакта совсем! -for red
    }
}
 
"abcd"|test
test 'efgh'
""|test
0
2807 / 505 / 121
Регистрация: 26.09.2020
Сообщений: 954
Записей в блоге: 5
23.04.2025, 19:20
YuS_2, так проверяется наличие параметра, а надо, как я понял, по трубе поступил параметр или нет.

$input — по трубе:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Test {
    param (
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $param
    )
 
    process {
        if ($input) {
            Write-Host "$param - Сила Сибири!" -ForegroundColor Cyan
        } else {
            $param | % {Write-Host "$_ - СПГ" -ForegroundColor DarkGray}
        }
    }
}
 
'abcd', 'dcba' | test
test 'abcd', 'dcba'
'' | test
[PSCustomObject]@{param = 'efgh', 'hgfe'; neparam = 'klmn'} | test
1
Любознательный
 Аватар для YuS_2
7407 / 2260 / 361
Регистрация: 10.03.2016
Сообщений: 5,216
24.04.2025, 09:26
Цитата Сообщение от iNNOKENTIY21 Посмотреть сообщение
так проверяется наличие параметра, а надо, как я понял, по трубе поступил параметр или нет.
Ну, хз... нас, самаритян тут километр...
Но вот, лично я, до сих пор не на все 100 понял, чего требуется-то.
Как понял я:
Нужно создать командлет у которого параметр может приниматься по трубе и(или) может быть объявлен как позиционный, без указания конкретного имени параметра. Проверка наличия, вроде бы, не требовалась... у меня проверка исключительно для демонстрации, что данные командлетом принимаются. Но да, тут может быть, как раз требовалась демонстрация того, что параметр принимается по наименованию (как у тебя сделано), т.к. по трубе может передаваться сразу несколько, как и позиционно, без наименований, тоже может быть их несколько.
0
 Аватар для volodin661
7097 / 2328 / 353
Регистрация: 10.12.2013
Сообщений: 8,051
24.04.2025, 10:29
страшное дело этот ваш powershell,
трехчасовое блуждание между трех сосен,
то работает, то не работает,
таинственные преобразования типов.
в связи с последним один практический рецепт точно можно дать - никогда,
вы слышите? - никогда не пытайтесь корчить из себя программиста и подсказывать этому дяде,
какой тип должно принимать выражение. прогадаете. пусть уж он сам.
0
2807 / 505 / 121
Регистрация: 26.09.2020
Сообщений: 954
Записей в блоге: 5
24.04.2025, 19:23
Раз уже не надо сортировать файлы и добрались до классов, то надо бы и до интерфейсов дотянуться (IComparable)
Sort-Object это использует и будет сортировать согласно сравнивалке.

Вот, на всё той же сравнивалке из winapi примерная реализация:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Add-Type @'
using System;
using System.Collections;
using System.Runtime.InteropServices;
 
public class LogicalStringComparer : IComparer
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    public static extern int StrCmpLogicalW(string s1, string s2);
 
    public int Compare(object x, object y)
    {
        return StrCmpLogicalW(x as string, y as string);
    }
}
'@
 
class Cell : IComparable {
    [int] $Number
    [string] $Name
    [string] $Definition
 
    [string] ToString() {
        return '{0:000#}({1})' -f $this.Number, $this.Name
    }
 
    [int] CompareTo([object] $obj) {
        if (-not ($obj -is [Cell])) {
            throw 'Cell: CompareTo: $obj — Не [Cell]'
        }
 
        $o = [Cell] $obj
        $comparer = [LogicalStringComparer]::new()
        return $comparer.Compare($this.Name, $o.Name)
    }
}
все классы для работа примера, обратно в файл не реализовано…

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
Add-Type @'
using System;
using System.Collections;
using System.Runtime.InteropServices;
 
public class LogicalStringComparer : IComparer
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    public static extern int StrCmpLogicalW(string s1, string s2);
 
    public int Compare(object x, object y)
    {
        return StrCmpLogicalW(x as string, y as string);
    }
}
'@
 
class Cell : IComparable {
    [int] $Number
    [string] $Name
    [string] $Definition
 
    [string] ToString() {
        return '{0:000#}({1})' -f $this.Number, $this.Name
    }
 
    [int] CompareTo([object] $obj) {
        if (-not ($obj -is [Cell])) {
            throw 'Cell: CompareTo: $obj — Не [Cell]-ka'
        }
 
        $o = [Cell] $obj
        $comparer = [LogicalStringComparer]::new()
        return $comparer.Compare($this.Name, $o.Name)
    }
}
 
class Dump {
    [string] $Name
    [datetime] $Created
    $Cells = [System.Collections.Generic.List[Cell]]::new()
 
    Dump([string] $content) {
        if ([string]::IsNullOrWhiteSpace($content)) {
            throw "Dump: content не может быть пустым или состоять из пробелов!"
        }
 
        $this.Parse($content)
        $this.Created = Get-Date
        $this.Name = 'Дамп от: {0}' -f $this.Created
    }
 
    [string] ToString() {
        return $this.Name
    }
 
    hidden [void] Parse([string] $content) {
        $m = [regex]::Matches($content, 'O(\d+)\((.+)\)')
 
        $m.GetEnumerator() | ForEach-Object {
            $start = $_.Index + $_.Length
            $next = $_.NextMatch().Index
 
            if ($next -le $start) {
                $next = $content.Length
            }
 
            $length = $next - $start
 
            $cell = [Cell] @{
                Number     = $_.Groups[1].Value
                Name       = $_.Groups[2].Value
                Definition = $content.Substring($start, $length)
            }
 
            $this.Cells.Add($cell)
        }
    }
}
 
class DumpFile {
    [System.IO.FileInfo] $File
 
    DumpFile([string] $FullName) {
        try {
            $this.File = Get-Item -LiteralPath $FullName -ErrorAction Stop
        } catch {
            throw "Не найден файл: «$FullName». $_"
        }
    }
 
    [string] ToString() {
        return $this.File.FullName
    }
 
    hidden [string] GetContent() {
        try {
            $GetContentSplat = @{
                LiteralPath = $this.File.FullName
                Raw = $true
                ErrorAction = 'Stop'
            }
 
            return (Get-Content @GetContentSplat).Trim('%')
        } catch {
            throw "Не удалось прочитать файл «$($this.File.FullName)». $_"
        }
    }
 
    hidden static DumpFile() {
        $ContentProperty = @{
            MemberType = 'ScriptProperty'
            MemberName = 'Content'
            Value      = { $this.GetContent() }
        }
 
        'DumpFile' | Update-TypeData @ContentProperty
 
        $DumpProperty = @{
            MemberType = 'ScriptProperty'
            MemberName = 'Dump'
            Value      = { return [Dump]::new($this.Content) }
        }
 
        'DumpFile' | Update-TypeData @DumpProperty
    }
}
 
# использовать
$path = 'F:\Downloads\All-Prog 22.04.25(Со станка).TXT'
$dumpFile = [DumpFile]::new($path)
$cells = $dumpFile.Dump.Cells
 
$cells | Where-Object Name -Match UVAI | Sort-Object
 
# для сравнения и выявления изменений до и поле сортировки
# $cells | Out-File F:\Downloads\dump.txt
# $cells | Sort-Object | Out-File F:\Downloads\dump-sorted.txt
# winmerge.exe F:\Downloads\dump.txt F:\Downloads\dump-sorted.txt


многословно получилось.
2
 Аватар для volodin661
7097 / 2328 / 353
Регистрация: 10.12.2013
Сообщений: 8,051
25.04.2025, 03:21
iNNOKENTIY21,
всё отлично; уровни сравнения только добавить.
0
Любознательный
 Аватар для YuS_2
7407 / 2260 / 361
Регистрация: 10.03.2016
Сообщений: 5,216
25.04.2025, 09:45
Цитата Сообщение от iNNOKENTIY21 Посмотреть сообщение
Раз уже не надо сортировать файлы и добрались до классов, то надо бы и до интерфейсов дотянуться
ну, началось... классы, библиотеки, интерфейсы... тогда уж программу на C# и голову не морочить шутка

Цитата Сообщение от volodin661 Посмотреть сообщение
вы слышите? - никогда не пытайтесь корчить из себя программиста и подсказывать этому дяде,
какой тип должно принимать выражение. прогадаете. пусть уж он сам.
Да ладно... сам... он иногда такие загогулины выдает - хоть стой, хоть падай. Изредка, пока специально типом его не пнешь, нифига не взлетает. Так что, для профилактики иногда полезно покорчиться в муках и выдать подсказку.
0
2807 / 505 / 121
Регистрация: 26.09.2020
Сообщений: 954
Записей в блоге: 5
25.04.2025, 17:40
Цитата Сообщение от volodin661 Посмотреть сообщение
уровни сравнения только добавить.
Что за уровни сравнения?
0
 Аватар для volodin661
7097 / 2328 / 353
Регистрация: 10.12.2013
Сообщений: 8,051
25.04.2025, 23:29
я не виноват, они так на своём американском пишут.
множественные критерии сортировки
0
2807 / 505 / 121
Регистрация: 26.09.2020
Сообщений: 954
Записей в блоге: 5
26.04.2025, 18:28
Разбить объект на составляющие, а-ка декомпозиция.
типа такого:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class ProgramName {
    [string] $Name
 
    [string] ToString() {
        return $this.Name
    }
 
    [int] CompareTo([object] $obj) {
        if (-not ($obj -is [Cell])) {
            throw 'Cell: CompareTo: $obj — Не [Cell]'
        }
 
        $o = [Cell] $obj
        $comparer = [LogicalStringComparer]::new()
        return $comparer.Compare($this.Name, $o.Name)
    }
}
 
class Cell {
    [int] $Number
    [ProgramName] $ProgramName
    [string] $Definition
 
    [string] ToString() {
        return 'O{0:000#}({1})' -f $this.Number, $this.ProgramName.Name
    }
}
Обращения к свойству cell.Name придётся заменять, например в парсере:
PowerShell
1
2
3
4
5
$cell = [Cell] @{
    Number      = $_.Groups[1].Value
    ProgramName = [ProgramName] @{ Name = $_.Groups[2].Value }
    Definition  = $content.Substring($start, $length)
}
и при сортировке указывать свойство сортировки: ProgramName и другие, станет обязательно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.04.2025, 18:28

Групповое переименование файлов
Прошу прощения, если повторюсь и где-то уже дан ответ на этот вопрос, но я, к сожалению, не нашёл....

Групповое переименование файлов по маске
Доброго времени суток! В написании командных скриптов только разбираюсь. Помогите, пожалуйста,...

Групповое переименование файлов
Надеюсь, что раздел выбрал правильно. Подскажите пожалуйста, как переименовать файлы вида ...

Неправильная сортировка при групповом переименовании файлов
Имеются файлы вида 1.ext,2ext...100.ext... Задача привести их к виду скажем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
91
Ответ Создать тему
Новые блоги и статьи
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru