Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/10: Рейтинг темы: голосов - 10, средняя оценка - 4.80
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
1

Перемещение файлов\папок по 2-м txt спискам (источник -> назначение)

12.07.2019, 00:23. Просмотров 1868. Ответов 22

Здравствуйте, нужен батник кот. запускается из фиксированного места, занимается тем что, меняет пути (фактически перемещает или переименовывает) к файлам и папкам, указаные в строках Source.txt на те, что указаны в Destin.txt.

Имеются 2 txt файла, (источник и получатель) внутри полные пути к файлам\папкам.

в Source.txt пути к реально существующим файлам\папкам:

c:\Folder One\Имя файла.ext
d:\Folder One\Имя файла.ext
e:\Folder Other\Имя другого файла.ext
f:\Folder One\Folder Two\

в Destin.txt пути назначения, куда перемещать файлы

d:\Folder 7\Folder\Another\Имя файла.ext
а:\Folder 1\Имя 2 файла.ext
e:\Folder Other\Имя ещё одного файла.ext
f:\Folder One\Folder Five\

Строки файла Source.txt строго соответствуют строкам файла Destin.txt
Файл или папка в 1 строке Source.txt перемещается или переименовывается в соответствии с 1 строкой Destin.txt
Папки в txt списках заканчиваются слешем \
Перемещние с источника на получатель может быть на разные диски (как показано в примере)
В системе подключён сетевой диск, не знаю, возможно это и не важно но нужно чтобы батник адекватно перемещал файлы и на нём.

Внутри txt у строк у меня нет кавычек

Система Win 7, 64.

P.S. много похожих тем на форуме, в том числе и перемещения по списку источнику, но чтобы в качестве получателя тоже был список на форуме я не нашёл.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.07.2019, 00:23
Ответы с готовыми решениями:

Создание папок с именами заданных файлов и перемещение этих файлов в созданные папки
Подскажите пожалуйста как по названиям файлов txt создать папки и положить в каждую из папок файл с...

Перемещение файлов из папок в одну
Добрый день, помогите создать bat, который бы выполнял следущую операцию: В одной папке находится...

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

Создание папок и перемещение в них файлов по списку
Доброго времени суток! Собственно, вопрос в следующем: Имеется список файлов текущего каталога...

Перемещение файлов из папки в несколько папок по 1000 штук
Здравствуйте! Помогите решить задачу, плиз. Есть папка, содержащая примерно 30 000 xml-файлов...

22
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
12.07.2019, 00:52 2
SteamStyx, без массивов и коллекций бат в данном случае — плохой выбор. Или нужно делать в одном списке, где на строке старый путь>новый путь.

Цитата Сообщение от SteamStyx Посмотреть сообщение
на форуме я не нашёл.
Только недавно приводил: Переименовать массив файлов через ТХТ
1
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
12.07.2019, 01:52 3
PowerShell
1
2
3
4
5
6
7
8
9
10
$a = (gc source.txt).GetEnumerator()
 
$b = (gc destin.txt).GetEnumerator()
 
while( $a.MoveNext() ) { 
 
    $b.MoveNext();
 
    Move-Item -Path $a.Current -Destination $b.Current  -force
}
Добавлено через 33 минуты
PS: небрежно проверил под Linux pwsh версия 6.2, работает. под Powershell for Windows не проверял; на именах файлов с пробелами не проверял.
1
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
12.07.2019, 02:40 4
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
iList = "Source.txt"
oList = "Destin.txt"
 
With CreateObject("Scripting.FileSystemObject")
  iList = Split(.OpenTextFile(iList).ReadAll, vbCrLf)
  oList = Split(.OpenTextFile(oList).ReadAll, vbCrLf)
  For i = 0 To Ubound(iList)
    nPath = .GetAbsolutePathName(oList(i))
    If RIght(iList(i), 1) = "\" Then Set F = .GetFolder(iList(i)) Else Set F = .GetFile(iList(i))
    If Not StrComp(F.Drive, Left(nPath, 2)) Then F.Move nPath Else F.Copy nPath: F.Delete
  Next
End With
1
12.07.2019, 02:40
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
12.07.2019, 03:37 5
Вариант 2: ( реализация 'Zip-оператора' и генерация соответств. bat-файла )

PowerShell
1
2
3
4
5
6
7
8
function ZZ { [CmdletBinding()]
 
    Param( $First, $Second, $ResultSelector = { ,$args } )
 
    [System.Linq.Enumerable]::Zip($First, $Second, [Func[Object, Object, Object[]]]$ResultSelector)
}
 
ZZ (gc source.txt) (gc destin.txt) { param($a, $b) '@move "{0}" "{1}"' -f $a,$b } > doit.bat
Output: doit.bat
Код
@move "c:\Folder One\Имя файла.ext" "d:\Folder 7\Folder\Another\Имя файла.ext"
@move "d:\Folder One\Имя файла.ext" "а:\Folder 1\Имя 2 файла.ext"
@move "e:\Folder Other\Имя другого файла.ext" "e:\Folder Other\Имя ещё одного файла.ext"
@move "f:\Folder One\Folder Two\" "f:\Folder One\Folder Five\"
1
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
12.07.2019, 12:11  [ТС] 6
FlasherX, bidstrup Спасибо вам огромное, за ответы, с PowerShell лично мне тяжелее это реализовать, что-то не получается, наверное где-то мой косяк, но всё же:

Пытаюсь переместить файл q:\Move\Ghibli Disc.jpg -> q:\Move\Dest Folder\Ghibli Disc.jpg

Скрипт из 1 Варианта
Запуск происходит из bat, внутри: powershell -exec bypass "q:\Move\MoveFromTXT.ps1"
Сам файл "MoveFromTXT.ps1" пробовал в разных кодировках: Кирилица Windows\Dos; UTF-8\UTF-16 LE
PowerShell version: 6.2.1

выдаёт много строк ошибок:

q:\Move>powershell -exec bypass "q:\Move\MoveFromTXT.ps1"
True
Move-Item : Cannot find path 'Q:\Move"' because it does not exist.
At Q:\Move\MoveFromTXT.ps1:9 char:5
+ Move-Item -Path $a.Current -Destination $b.Current -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Q:\Move":String) [Move-Item],
ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
temCommand

True
...
Cannot find path 'Q:\Move\i' because it does not exist.
...
Cannot find path 'Q:\Move\b' because it does not exist.
...
Cannot find path 'Q:\Move\l' because it does not exist.

и.т.д.


FlasherX, с VBS код работает отлично, но есть одно но - если каталога - получателя не существует, скрипт выдаёт ошибку, возможно поправить, чтобы каталоги создавались до перемещения в них файлов?

Ещё раз, спасибо вам большое!

Добавлено через 12 минут
FlasherX, да, почему-то папки скрипт не перемещает:

source.txt:
q:\Move\Папка источник\

destin.txt:
a:\Folder\

Обе папки существуют, в "q:\Move\Папка источник" есть 1 файл, соответственно ожидается, что этот файл просто окажется по пути "a:\Folder\Файл.ext"
0
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
12.07.2019, 13:04 7
Цитата Сообщение от SteamStyx Посмотреть сообщение
если каталога - получателя не существует, скрипт выдаёт ошибку
Если крайнего нет, то ошибки быть не должно. Только если вышестоящих нет.
Цитата Сообщение от SteamStyx Посмотреть сообщение
Обе папки существуют
Перенос только содержимого и не предполагался в ТЗ. Речь шла о переносе самих папок/файлов.
1
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
12.07.2019, 13:29 8
Дорогой друг, инструментом автоматизации в Windows является Powershell.
Придётся с этим смириться.
Никакого cmd не надо. Хорошая новость - тебе не надо тратить на него время своей жизни.

Отладка происходит в среде powershell.
Для отладки делаешь 2 списка с существующими директориями, по две строчки в каждом списке.
Постепенно усложняешь и выявляешь те случаи, при которых появляется ошибка.
0
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
12.07.2019, 14:01 9
SteamStyx, подправил под нужны. Проверяйте:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
iList = "Source.txt"
oList = "Destin.txt"
 
Set Shell = CreateObject("Shell.Application")
With CreateObject("Scripting.FileSystemObject")
  iList = Split(.OpenTextFile(iList).ReadAll, vbCrLf)
  oList = Split(.OpenTextFile(oList).ReadAll, vbCrLf)
  For i = 0 To Ubound(iList)
    Check = 1
    iPath = .GetAbsolutePathName(iList(i))
    nPath = .GetAbsolutePathName(oList(i))
    If .FolderExists(iList(i)) Then
      Set F = .GetFolder(iPath)
      If Not .FolderExists(.GetParentFolderName(nPath)) Then Shell.NameSpace(.GetDriveName(nPath)).NewFolder Mid(nPath, 4)
    ElseIf .FileExists(iPath) Then Set F = .GetFile(iPath)
    Else Check = 0 End If
    If Check Then If Not StrComp(F.Drive, .GetDriveName(nPath)) Then F.Move nPath Else F.Copy nPath: F.Delete
  Next
End With
1
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
12.07.2019, 16:26  [ТС] 10
FlasherX По второму скрипту:

Файлы:

source.txt:
q:\Move\Файл источник.jpg

destin.txt:
q:\Move\111\Файл получатель.jpg

если до запуска скрипта, папки "q:\Move\111" не существует - выдаёт ошибку.

Line: 17, Char: 70, Path not found

если до запуска скрипта, папка "q:\Move\111" существует - работает.

---------

Папки:

source.txt:
q:\Move\Папка Источник\

destin.txt:
q:\Move\Папка Получатель\

если до запуска скрипта, "Папка Получатель" существует - выдаёт ошибку,
не существует - скрипт работает.
если в строке destin.txt: у нового адреса папки будет несколько вложений, например "q:\Move\Папка Получатель\Ещё папка\" - выдаёт ошибку.


bidstrup По второму скрипту:

PowerShell
1
2
3
4
5
6
Cannot find an overload for "Zip" and the argument count: "3".
At Q:\Move\MoveFromTXT.ps1:5 char:5
+     [System.Linq.Enumerable]::Zip($First, $Second, [Func[Object, Obje ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
Цитата Сообщение от bidstrup Посмотреть сообщение
Придётся с этим смириться.
Никаких предубеждений, просто он у меня не работает
0
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
12.07.2019, 21:40 11
Лучший ответ Сообщение было отмечено SteamStyx как решение

Решение

Цитата Сообщение от SteamStyx Посмотреть сообщение
если до запуска скрипта, "Папка Получатель" существует - выдаёт ошибку,
Дело не в этом, а том, что в вашем примере та же родительская папка. Т.е. перемещать тут нечего, нужно только переименовать.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
iList = "Source.txt"
oList = "Destin.txt"
 
Set Shell = CreateObject("Shell.Application")
With CreateObject("Scripting.FileSystemObject")
  iList = Split(.OpenTextFile(iList).ReadAll, vbCrLf)
  oList = Split(.OpenTextFile(oList).ReadAll, vbCrLf)
  For i = 0 To Ubound(iList)
    Check = 1
    iPath = .GetAbsolutePathName(iList(i))
    nPath = .GetAbsolutePathName(oList(i))
    Parent = .GetParentFolderName(nPath)
    If Not .FolderExists(Parent) Then Shell.NameSpace(.GetDriveName(nPath)).NewFolder Mid(Parent, 4)
    If .FolderExists(iList(i)) Then
      Set F = .GetFolder(iPath)
    ElseIf .FileExists(iPath) Then Set F = .GetFile(iPath)
    Else Check = 0 End If
    If Check Then If Parent = .GetParentFolderName(iPath) Then F.Name = .GetFileName(nPath) Else _
    If Not StrComp(F.Drive, .GetDriveName(nPath)) Then F.Move nPath Else F.Copy nPath: F.Delete
  Next
End With
1
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
12.07.2019, 23:11 12
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
$a = (gc source.txt).GetEnumerator()
 
$b = (gc destin.txt).GetEnumerator()
 
while( $a.MoveNext() ) { 
 
    $b.MoveNext();
    
    New-Item -Type Directory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
 
    Move-Item -Path $a.Current -Destination $b.Current  -Force 
}
0
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
15.07.2019, 20:33  [ТС] 13
FlasherX, vbs скрипт работает великолепно; к счастью не к чему придраться, огромнеёшее вам спасибо!

bidstrup страюсь с Powershell, так и не получается:

- Запустил простейший скрипт:

PowerShell
1
2
3
4
5
$path = "C:\Move\NewFolder"
If(!(test-path $path))
{
New-Item -ItemType Directory -Force -Path $path
}
Скрипт сработал - значит Powershell у меня работает, - заключил я.

- Указывал внутри тхт источник -> получатель в кавычках
- Прописывал полные пути к source\destin в скрипте в кавычках
- Изменял кодировки скрипта .ps1 и двух файлов-списков: utf-8 \ utf-16 \ Cyrillic
- перенёс запуск на диск С:\

Итак, 3 файла в utf-8 without signature:

c:\Move\source.txt
c:\Move\1.jpg
c:\Move\destin.txt
c:\Move\2.jpg
c:\Move\MoveScript.ps1
Запускается так: powershell -noexit -executionpolicy bypass c:\Move\MoveScript.ps1
или так: powershell -noexit -executionpolicy bypass -File "c:\Move\MoveScript.ps1"

+ подопытный файл, без кирилицы и пробелов в пути:
c:\Move\1.jpg

Вот что выдаёт:

Кликните здесь для просмотра всего текста

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\c' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\c:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\:' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\::String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,M
   icrosoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot move item because the item at 'C:\' is in use.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Move-Item], PSInvalidOper
   ationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.M
   oveItemCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\M' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\M:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\o' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\o:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\v' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\v:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\e' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\e:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,M
   icrosoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot move item because the item at 'C:\' is in use.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Move-Item], PSInvalidOper
   ationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.M
   oveItemCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\1' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\1:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot move item because the item at 'C:\Move' is in use.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Move-Item], PSInvalidOper
   ationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.M
   oveItemCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\j' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\j:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\p' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\p:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
 
True
New-Item : Cannot bind argument to parameter 'Path' because it is an empty
string.
At C:\Move\MoveScript.ps1:9 char:36
+ ... rectory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-Item], ParameterBindingVal
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl
   lowed,Microsoft.PowerShell.Commands.NewItemCommand
 
Move-Item : Cannot find path 'C:\Move\g' because it does not exist.
At C:\Move\MoveScript.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Move\g:String) [Move-Item],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveI
   temCommand
0
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
16.07.2019, 02:13 14
Что ж, обнаружилось весьма интересное поведение метода GetEnumerator(),
который потрошит строку посимвольно, если последняя не заканчивается символом перевода строки.
То есть, строка "c:\Move\1.jpg" без перевода строки для перечислителя выглядит вот так:
Код
c
:
\
M
o
v
e
\
1
.
j
p
g
И теперь становится понятно, откуда взялась эта одинокая буква c в сообщении
Move-Item : Cannot find path 'C:\Move\c' because it does not exist.

У меня этот эффект при тестировании не проявился, поскольку тестировал я файл, где было много строк и все строки, соответственно, имели символ перевода строки.

Иными словами, это моя безоговорочная ошибка.
Исправляется она явным привидением типа результата чтения содержимого файла к String[] перед вызовом метода GetEnumerator()

$a = ([String[]](gc source.txt)).GetEnumerator()
$b = ([String[]](gc destin.txt)).GetEnumerator()


либо просто добавить собаку перед скобками:

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
$a = @(gc source.txt).GetEnumerator()
 
$b = @(gc destin.txt).GetEnumerator()
 
while( $a.MoveNext() ) { 
 
    $b.MoveNext();
    
    New-Item -Type Directory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force
 
    Move-Item -Path $a.Current -Destination $b.Current  -Force 
}
1
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
16.07.2019, 13:13  [ТС] 15
bidstrup, С файлами замечательно работает!, есть несколько замечаний по папкам:

Ситуация №1: Есть, папка, TFLD, там 3 файлика, вот содержимое строк источник -> назначение:
S.txt: c:\Move\TFLD\
D.txt: c:\Move\TFLD2\
Получается, что создаётся "c:\Move\TFLD2" внутрь помещается папка "TFLD", со своим содержимым, а нужно как-бы переименовать папку TFLD в TFLD2

Ситуация №2:

S.txt: c:\Move\TFLD\Папка с содержимым\
D.txt: c:\Move\TFLD\
Результат:

Кликните здесь для просмотра всего текста

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
True
 
 
    Directory: C:\Move
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019.07.16     12:40                TFLD
Move-Item : Source and destination path must be different.
At C:\Move\MoveDestinToSource.ps1:11 char:5
+     Move-Item -Path $a.Current -Destination $b.Current  -Force
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Move\TFLD\Папка с содержимым\:Di
   rectoryInfo) [Move-Item], IOException
    + FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Co
   mmands.MoveItemCommand
 
PS C:\Move\TFLD>


Можно сделать так, чтобы содержимое внутри "c:\Move\TFLD\Папка с содержимым" было бы перемещено в новый путь "c:\Move\TFLD"


FlasherX, Простите, у меня появилось ещё пожелание: если это не сложно, не могли бы вы добавить условие, если строка в файле источнике (source.txt) совпадает со строкой в получателе (никаких изменений в строках), то скрипт не выдавал бы ошибку, а просто переходил к следующей строке.
0
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
16.07.2019, 20:58 16
Цитата Сообщение от SteamStyx Посмотреть сообщение
Ситуация №1: Есть, папка, TFLD, там 3 файлика, вот содержимое строк источник -> назначение:
Код
S.txt: c:\Move\TFLD\
Код
D.txt: c:\Move\TFLD2\
Вариант:
если у строки источника и назначения на самом хвосте живёт символ-разделитель путей ( '\' для Windows; '/' для Linux,Macos)
то применяется не Move-Item, а Rename-Item

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$a = @(gc source.txt).GetEnumerator()
$b = @(gc destin.txt).GetEnumerator()
 
while( $a.MoveNext() ) { 
 
    $b.MoveNext();
 
    $az = $a.current.substring($a.current.length-1)
    $bz = $b.current.substring($b.current.length-1) 
 
 
    if ( ($az -eq $bz) -and ($az -eq [System.IO.Path]::PathSeparator) ) {
    
        Rename-Item -Path $a.current -NewName $b.current -Force
    } else {
    
        New-Item -Type Directory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force      
        Move-Item -Path $a.Current -Destination $b.Current  -Force
    }       
 
}
0
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
16.07.2019, 21:10 17
Лучший ответ Сообщение было отмечено SteamStyx как решение

Решение

SteamStyx, конечно:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
iList = "Source.txt"
oList = "Destin.txt"
 
Set Shell = CreateObject("Shell.Application")
With CreateObject("Scripting.FileSystemObject")
  iList = Split(.OpenTextFile(iList).ReadAll, vbCrLf)
  oList = Split(.OpenTextFile(oList).ReadAll, vbCrLf)
  For i = 0 To Ubound(iList)
    Check = 1
    iPath = .GetAbsolutePathName(iList(i))
    nPath = .GetAbsolutePathName(oList(i))
    If StrComp(iPath, nPath, 1) Then
      Parent = .GetParentFolderName(nPath)
      Shell.NameSpace(.GetDriveName(nPath)).NewFolder Mid(Parent, 4)
      If .FolderExists(iList(i)) Then
        Set F = .GetFolder(iPath)
      ElseIf .FileExists(iPath) Then Set F = .GetFile(iPath)
      Else Check = 0 End If
      If Check Then If Parent = .GetParentFolderName(iPath) Then F.Name = .GetFileName(nPath) Else _
      If Not StrComp(F.Drive, .GetDriveName(nPath), 1) Then F.Move nPath Else F.Copy nPath: F.Delete
    End If
  Next
End With
1
bidstrup
292 / 115 / 16
Регистрация: 11.03.2018
Сообщений: 504
16.07.2019, 21:49 18
код из #16 считать недействительным, Rename-Item пока отложим в сторону
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$a = @(gc source.txt).GetEnumerator()
$b = @(gc destin.txt).GetEnumerator()
 
while( $a.MoveNext() ) { 
 
    $b.MoveNext();
    
    $az = $a.current.substring($a.current.length-1)
    $bz = $b.current.substring($b.current.length-1) 
 
    if ( ($az -eq $bz) -and ($az -eq [System.IO.Path]::DirectorySeparatorChar) ) {
    
        Move-Item $a.current $b.current 
    } else {
    
        New-Item -Type Directory -Path ([System.IO.Path]::GetDirectoryName($b.Current)) -Force      
        Move-Item -Path $a.Current -Destination $b.Current  -Force
    }       
}
0
SteamStyx
0 / 0 / 0
Регистрация: 31.05.2018
Сообщений: 7
Вчера, 13:15  [ТС] 19
bidstrup, код от 2019.07.16 - 21:49

[+] Переименование папки не меняя пути
[+] Папка с содержимым в другую существующую папку
[-\+] Папка с содержимым в несуществующую папку
[-] Папка с содержимым на ур вверх

[+] Переименование файла не меняя пути
[+] Файл на ур вверх
[+] Файл в существующую папку
[+] Файл в несуществующую папку

------------------------------------------------------

[-] Папка с содержимым в несуществующую папку, глубже уровнем

source.txt C:\Move\TFLD\testfold1\
destin.txt: C:\Move\TFLD\NEW\testfold1\
Кликните здесь для просмотра всего текста

PowerShell
1
2
3
4
5
6
7
8
9
10
11
True
Move-Item : Could not find a part of the path.
At C:\Move\MoveDestinToSource.ps1:13 char:9
+         Move-Item $a.current $b.current
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Move\TFLD\testfold1\:DirectoryIn
   fo) [Move-Item], DirectoryNotFoundException
    + FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Co
   mmands.MoveItemCommand
 
PS C:\Move\TFLD>


*VBS корректно исполняет это, Powerscript - увы


[+] Папка с содержимым в несуществующую папку, выше уровнем

source.txt C:\Move\TFLD\testfold1\
destin.txt: C:\Move\testfold1\
Работает


А, с операцией ниже - спорно, наверное скрипт действует правильно и никакой ошибки тут нет, в общем поглядите, возможно ли это как то обойти - если нельзя, то претензий к этой ошибке у меня на самом деле нет:

[-] Папка с содержимым в существующую папку, выше уровнем

source.txt C:\Move\TFLD\testfold1\
destin.txt: C:\Move\TFLD\
Кликните здесь для просмотра всего текста

PowerShell
1
2
3
4
5
6
7
8
9
10
11
True
Move-Item : Source and destination path must be different.
At C:\Move\MoveDestinToSource.ps1:13 char:9
+         Move-Item $a.current $b.current
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Move\TFLD\testfold1\:DirectoryIn
   fo) [Move-Item], IOException
    + FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Co
   mmands.MoveItemCommand
 
PS C:\Move\TFLD>


*VBS скрипт также в недоумении выдаёт ошибку, (File already exits) в общем-то я понимаю на что и почему они оба ругаются.


FlasherX, спасибо, всё корректно.
0
FlasherX
1165 / 611 / 236
Регистрация: 06.06.2017
Сообщений: 2,278
Вчера, 14:21 20
Цитата Сообщение от SteamStyx Посмотреть сообщение
VBS скрипт также в недоумении выдаёт ошибку
И даже такие нестыковки в списках есть.
Visual Basic
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
Option Explicit
Dim iList, oList, Shell, i, Check, iPath, nPath, Parent, F
iList = "Source.txt"
oList = "Destin.txt"
 
Set Shell = CreateObject("Shell.Application")
With CreateObject("Scripting.FileSystemObject")
  iList = Split(.OpenTextFile(iList).ReadAll, vbCrLf)
  oList = Split(.OpenTextFile(oList).ReadAll, vbCrLf)
  For i = 0 To Ubound(iList)
    Check = 1
    iPath = .GetAbsolutePathName(iList(i))
    nPath = .GetAbsolutePathName(oList(i))
    If StrComp(iPath, nPath, 1) * StrComp(.GetParentFolderName(iPath), nPath, 1) Then
      Parent = .GetParentFolderName(nPath)
      Shell.NameSpace(.GetDriveName(nPath)).NewFolder Mid(Parent, 4)
      If .FolderExists(iPath) Then
        Set F = .GetFolder(iPath)
      ElseIf .FileExists(iPath) Then Set F = .GetFile(iPath)
      Else Check = 0 End If
      If Check Then If Not StrComp(Parent, F.ParentFolder, 1) Then F.Name = .GetFileName(nPath) Else _
      If Not StrComp(F.Drive, .GetDriveName(nPath), 1) Then F.Move nPath Else F.Copy nPath: F.Delete
    End If
  Next
End With
1
Вчера, 14:21
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
Вчера, 14:21

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

Консольное приложение: отображение структуры файлов и папок, перемещение по папкам, открытие файлов
Приложение написанное на языке СИ позволяющее в консольном режиме отображать структуру файлов и...

1С Документооборот 8 ПРОФ, редакция 2.1. Назначение прав на добавление папок и файлов
Здравствуйте. Конфигурация 1С Документооборот 8 ПРОФ, редакция 2.1 (2.1.7.9). Проблема с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru