PDA

Показать полную графическую версию : [решено] обрезать по заданному MAX PATH


Страниц : [1] 2

shadowbat
18-06-2010, 11:57
есть список
http://img33.imageshack.us/img33/4139/43116812.jpg

я нашел как только обрезать длину файла. т.е.:
http://img64.imageshack.us/img64/1778/48831148.jpg

а нужно именно обрезать по длине пути т.е. уровнять MAX PATH
http://img27.imageshack.us/img27/3761/86389051.jpg

1. причем желательно:
чтобы я мог выбрать длину MAX PATH до которого нужно обрезать
(т.е. нужно не до 255 а скажем до 200 чтобы при копировании файлов в другое место был разбег для глубины)

2. и обязательно сохранение расширения файла.

3. как сделать чтобы захватывались для обработки длины MAX PATH только файлы с расширением txt ?

kaster
18-06-2010, 12:04
список как создаешь? и где он хранится? или надо этим же скриптом создавать который будет проводить обрезку?
и еще, расширение входит в эти MAX_PATH?
ну и на последок, файлы нужно переименовать с новыми обрезанными названиями?

kaster
18-06-2010, 12:19
Попробуй вот такой код

#include <file.au3>
$MAX_PATH = 200
$sFolder = "Path to the folder with files"; Путь до папки содержащий файлы, которые надо обрезать
$aFiles = _FileListToArray($sFolder, "*.txt", 1)
For $i = 1 to $aFiles[0]
$sLongName = $sFolder & '\' & $aFiles[$i]
$sLongName_NoExt = StringTrimRight($sLongName, 4); Название без расширения
$sLongName_Ext = StringRight($sLongName, 3); Расширение
$sNewName_NoExt = StringLeft($sLongName_NoExt, $MAX_PATH); Обрезаем название файла без расришения до длины MAX_PATH
$sNewName = $sNewName_NoExt & "." & $sLongName_Ext; Добавляем расширение
FileMove($sLongName, $sNewName);Переименовывем файл
Next

Требования:

Все файлы с длинными названиями и расширением txt должны находится в некоторой папке, путь до которого нужно ввести в скрипте
Расширение в общую длину MAX_PATH не входит, то есть после обрезки общая длина пути файла будет MAX_PATH+4
Проверить работоспособность сначала на тестовых файлах, во избежания неправильной работы скрипта

shadowbat
18-06-2010, 12:20
список как создаешь? и где он хранится? или надо этим же скриптом создавать который будет проводить обрезку?
надо этим же скриптом создавать который будет проводить обрезку. наверное маска файлов, которые надо включать в список тут задается?


и еще, расширение входит в эти MAX_PATH?
не важно. +-4 символа роли не сыграют. как проще реализовать, так и сделать


ну и на последок, файлы нужно переименовать с новыми обрезанными названиями?
да, в этом главное предназначение - обрезать длину MAX PATH через переименование

kaster
18-06-2010, 12:23
надо этим же скриптом создавать который будет проводить обрезку »
в таком случае, надо говорить не "есть список", а "есть файлы".
не важно. »
с точки зрения скрипта тоже не важно. напишешь ты там MAX_PATH или MAX_PATH+-4. сложность одинаковая

shadowbat
18-06-2010, 12:26
Все файлы с длинными названиями и расширением txt должны находится в некоторой папке, путь до которого нужно ввести в скрипте

хм... а как настроить чтобы скрипт сам искал по маске *.txt ?
нужно сохранить дерево папок. там около 1800 путей с папками, подпапками и в конце пути один файл txt.
т.е. количество путей с папками = количеству файлов, которые нужно обрезать

Попробуй вот такой код
http://img41.imageshack.us/img41/2004/10727436.th.jpg (http://img41.imageshack.us/img41/2004/10727436.jpg)

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

kaster
18-06-2010, 12:31
shadowbat, мде... а хотя бы прочитать что там написано? в частности строка 3
$sFolder = "Path to the folder with files"; Путь до папки содержащий файлы, которые надо обрезать
где там путь? я думал, ввести путь сам догадаешься. я же не знаю где у тебя лежат файлы.
нужно сохранить дерево папок »
это усложняет задачу, т.к. рекурсивный поиск по подпапкам необходимо реализовывать вручную.
позже напишу, если никто более не откликнется

хм... а как настроить чтобы скрипт сам искал по маске *.txt ? »
скрипт и так ищет только файлы с расширением тхт. посмотри скрипт, хотя бы мельком.

shadowbat
18-06-2010, 12:35
shadowbat, мде... а хотя бы прочитать что там написано? в частности строка 3
$sFolder = "Path to the folder with files"; Путь до папки содержащий файлы, которые надо обрезать
где там путь? я думал, ввести путь сам догадаешься. я же не знаю где у тебя лежат файлы. »
=) так ты написал, что скрипт ищет работает только в одной папке, я по привычке и решил, что работает в той же папке что и сам без запроса пути

Попробуй вот такой код »
работает.

тогда осталось решить с путями.
что легче?:
1. рекурсивный поиск по подпапкам необходимо реализовывать вручную
либо
2. переместить файлы из всех папок и подпапок с сохранением пути откуда они были взяты. потом переименовка. потом перемещение назад фалы туда, откуда они были взяты


по поводу поиска:
а если реализовать например такой алгоритм?:

поиск файла *.txt
возвращение max path
переименовка
продолжить поиск

kaster
18-06-2010, 12:52
1. рекурсивный поиск по подпапкам необходимо реализовывать вручную »
это единственный путь, ибо п.2 - это абсурд, потому как в своей реализации содержит п.1 + кучу ненужных телодвижений и строк кода.
по поводу поиска:
а сложно реализовать например такой алгоритм?: »
смотря что ты подразумеваешь под поиском. если искать в той же папке, то скрипт выше. если включая подпапки, то это п.1 из списка выше, т.к. содержит рекурсию.

shadowbat
18-06-2010, 12:58
kaster, тогда еще вариант:
у меня есть список всех путей файлов.
можно ли, используя этот список, переименовывать файл с учетом max path?

т.е. получается не рекурсивный поиск, а просто работа по этим путям

shadowbat
18-06-2010, 13:56
кто может помочь?

вроде процедура стандартная. так сказать основополагающая. любой кто сталкивался с длинными именами должен иметь у себя в заначке методы работы с ними, как например обрезка по заданной длине...

kaster
18-06-2010, 14:44
shadowbat, а почему ты не хочешь изучить основы языка и самому реализовать такие простые вещи? тут главное нормально составить алгоритм и знать английский язык
попробуй вот так

#include <file.au3>
$MAX_PATH = 200
Global $sFolder = FileSelectFolder("Choose folder to processing", ""); Путь до папки содержащий файлы, которые надо обрезать
;Exit
If @error Then
MsgBox(48, 'Warning', 'The folder hasn''t been chosen. Script will be shut down now.', 3)
Exit
EndIf
_Main($sFolder)
Func _Main($path)
$aFiles = _FileListToArray($path, "*.txt", 1)
$aFolders = _FileListToArray($path, "*.txt", 2)
If Not IsArray($aFiles) AND Not IsArray($aFolders) Then
Return "" ;No files/folders found
EndIf
For $j = 1 to $aFolders[0]
$newpath = $path & '\' & $aFolders[$j]
_Main($newpath)
Next
For $i = 1 to $aFiles[0]
$sLongName = $path & '\' & $aFiles[$i]
_Renamer($sLongName)
Next

EndFunc

Func _Renamer($name)
$name_NoExt = StringTrimRight($name, 4); Название без расширения
$name_Ext = StringRight($name, 3); Расширение
$newname_NoExt = StringLeft($name_NoExt, $MAX_PATH); Обрезаем название файла без расришения до длины MAX_PATH
$newname = $newname_NoExt & "." & $name_Ext; Добавляем расширение
FileMove($name, $newname);Переименовывем файл
EndFunc

опять же, пробуй на свой страх и риск на тестовой файловой структуре с папками, подпапками и нужными файлами

shadowbat
18-06-2010, 15:36
shadowbat, а почему ты не хочешь изучить основы языка и самому реализовать такие простые вещи? тут главное нормально составить алгоритм и знать английский язык кто сказал что не хочу? я изучаю, конечно не так быстро как хотелось бы.


пробуй »
указываю путь и ничего не происходит. окно выбора папки закрывается и все. т.е. как будто скрипт должен сработать, но имена такие же как и были

kaster
18-06-2010, 15:48
я изучаю »
не в обиду сказано, но человек который действительно изучает, при виде ошибки делает как минимум 2 вещи
1. смотрит строчку с ошибкой, лезет в гугл/яндекс
2. открывает справку на предмет ошибочно написанной функции/процедуры.
с твоей стороны я наблюдаю обычный копипаст и удивленно круглые глаза, когда что-то не робит ;)
так. теперь по сути.
опять что то не так.. путь я указал »
это моя ошибка. вместо
$aFolders = _FileListToArray($path, "*.txt", 2)
напиши
$aFolders = _FileListToArray($path, "*", 2)
а по поводу путей, то там путь указывать не нужно. это всего лишь заголовок окна для указания папки.
защита от дурака ? »
не только. если убрать MsgBox, то это ко всему прочему способ предотвратить работу скрипта при нажатии на кнопку Esc или Cancel при выборе папки и тем самым нежелательных действий.

Посмотри вот этот тред. Часть скрипта взята оттуда. Поможет понять основы рекурсивной обработки папок
Построение дерева каталогов (http://forum.oszone.net/showthread.php?t=149119)

shadowbat
18-06-2010, 15:56
каждый профессионал в своем деле. или можно знать все и вся в любой момент времени по любой специализации..? профессионал бывает только в одной-двух областях. на любое познание требуется время. если Вы мне зададите вопрос по пережатию видео - я просто отвечу. мне будет уже приятно, что кому то помог.
после выбора папки вылетает (Line 16)
http://img188.imageshack.us/img188/2708/44913557.th.jpg (http://img188.imageshack.us/img188/2708/44913557.jpg)

Creat0R
18-06-2010, 15:59
вопрос - зачем тогда вписывать путь в скрипт? если он просит выбрать папку визуально через дерево папок »
Если указать путь вместо FileSelectFolder, то ничего просить не будет.

а что, если не выбирать путь? а настроить чтобы скрипт сам брала путь из той папки где она находится »
Вот тот же пример, но функцию «_Renamer» я немного изменил, используется RegExp:

#include <File.au3>

Global $MAX_PATH = 150
Global $sFolder = @ScriptDir ; Путь до папки содержащий файлы, которые надо обрезать

_Main($sFolder)

Func _Main($sPath)
$aFiles = _FileListToArray($sPath, "*.txt", 1)
$aFolders = _FileListToArray($sPath, "*", 2)

If Not IsArray($aFiles) And Not IsArray($aFolders) Then
Return "" ;No files/folders found
EndIf

For $j = 1 To UBound($aFolders)-1
_Main($sPath & '\' & $aFolders[$j])
Next

For $i = 1 To UBound($aFiles)-1
_Renamer($sPath & '\' & $aFiles[$i])
Next
EndFunc

Func _Renamer($sFile)
$sNewFile = StringRegExpReplace($sFile, '(.{' & $MAX_PATH & '}).*(\.[^\.]*$)', '\1\2'); Обрезаем название файла без расришения до длины MAX_PATH
FileMove($sFile, $sNewFile) ;Переименовывем файл
EndFunc

shadowbat
18-06-2010, 16:05
kaster, благодарю за помощь в этой теме
Creat0R, работает как часы.

рад, если кому то это решение тоже пригодится. (имеются ввиду будущие поколения :) )

РЕШЕНИЕ от Creat0R:
#include <File.au3>

Global $MAX_PATH = 150
Global $sFolder = @ScriptDir ; Путь до папки содержащий файлы, которые надо обрезать

_Main($sFolder)

Func _Main($sPath)
$aFiles = _FileListToArray($sPath, "*.txt", 1)
$aFolders = _FileListToArray($sPath, "*", 2)

If Not IsArray($aFiles) And Not IsArray($aFolders) Then
Return "" ;No files/folders found
EndIf

For $j = 1 To UBound($aFolders)-1
_Main($sPath & '\' & $aFolders[$j])
Next

For $i = 1 To UBound($aFiles)-1
_Renamer($sPath & '\' & $aFiles[$i])
Next
EndFunc

Func _Renamer($sFile)
$sNewFile = StringRegExpReplace($sFile, '(.{' & $MAX_PATH & '}).*(\.[^\.]*$)', '\1\2'); Обрезаем название файла без расришения до длины MAX_PATH
FileMove($sFile, $sNewFile) ;Переименовывем файл
EndFunc

Creat0R, а ты случайно не тот Creator, что участвует в разработке Opera AC ?
судя по твоим ссылкам в подписи - именно тот! пользуясь случаем хочу выразить неизмеримую благодарность. я на OAC второй год. и на другие браузеры пока даже смотреть не хочется. такого функционала как у OAC нигде нет, либо я пока не встречал

kaster
18-06-2010, 16:15
shadowbat
а так?

#include <file.au3>
#include <array.au3>
$MAX_PATH = 200
Global $sFolder = FileSelectFolder("Choose folder to processing", ""); Путь до папки содержащий файлы, которые надо обрезать
;Exit
If @error Then
MsgBox(48, 'Warning', 'The folder was''nt been chosen. Script will be shut off now.', 3)
Exit
EndIf
;MsgBox(0, '', $sFolder)
_Main($sFolder)
Func _Main($path)
ConsoleWrite($path & @CRLF)
$aFiles = _FileListToArray($path, "*.txt", 1)
$aFolders = _FileListToArray($path, "*", 2)
If IsArray($aFolders) Then
For $j = 1 to $aFolders[0]
$newpath = $path & '\' & $aFolders[$j]
_Main($newpath)
Next
EndIf
If IsArray($aFiles) Then
For $i = 1 to $aFiles[0]
$sLongName = $path & '\' & $aFiles[$i]
_Renamer($sLongName)
Next
EndIf
If Not IsArray($aFiles) AND Not IsArray($aFolders) Then
Return "" ;No files/folders found
EndIf
EndFunc

Func _Renamer($name)
$name_NoExt = StringTrimRight($name, 4); Название без расширения
$name_Ext = StringRight($name, 3); Расширение
$newname_NoExt = StringLeft($name_NoExt, $MAX_PATH); Обрезаем название файла без расришения до длины MAX_PATH
$newname = $newname_NoExt & "." & $name_Ext; Добавляем расширение
FileMove($name, $newname);Переименовывем файл
EndFunc

shadowbat
18-06-2010, 16:22
а так? » после выбора папки скрипт открыл окно с листингом входящих папок. я нажал на крестик. он выдал новое окно с листингом внутренних папок еще глубже. итак мне на тестовом примере показалось 10 окошек. я их все закрыл а после этого скрипт выкинул каждый переименованный файл на уровень выше от первичного местонахождения, но уже переименованый :)

Creat0R
18-06-2010, 16:48
ты случайно не тот Creator, что участвует в разработке Opera AC ? »
Тот :)




© OSzone.net 2001-2012