Что нового

[Данные, строки] Обработка текстовых файлов

Cfar

Новичок
Сообщения
3
Репутация
0
Версия AutoIt: 3.3.8.1

Описание:
Нужно автоматизировать процесс с текстовыми файлами - удаление строк в файлах, переименование файлов, подсчет цифровых значений с названия файла.

Примечания:
Ситуация такая - очень хочется разобраться в скриптовании, но т.к. работа сжигает все свободное время - не было достаточно времени для изучения самого процесса(более менее углубленно), поэтому решил совместить желание с реальностью.. Вот и решил обратиться к Вам за помощью на реальном исполнении(тема для меня актуальна по работе и использование справки по AutoIt на рабочей модели будет превосходным шансом научиться).
Задача такая:
1. В папке один или несколько текстовых файлов(к примеру расширение .cp) (в названии файла может использоваться русский язык и\или латиница) необходимо в файлах определить есть ли строки которые необходимо удалить, если они присутствуют - удалить(точно известно что это две строки в конце файла).
к примеру:
G01X0.000Y0.000
M02
2. После обработки файла изменить(добавить) название файла(любой спец символ в начале - для визуального определения что файл был обработан и для самой программы(для исключения повторной проверки файла).
3. В названии файла после определенного символа(к примеру "=") есть цифровое значение которое необходимо суммировать с остальными цифрами других файлов. (и в дальнейшем отобразить общую сумму всех файлов(с названия файлов и отдельно кол-во самих файлов) в выбранной для анализа папки)
... В голове насчет программы картинка такая - есть небольшое окно в которой расположены две кнопки ("подсчитать"(общее цифровое значение с названия всех выбранных файлов, так же количество самих файлов которые были обработаны) и "обработка" (чистка от строк)), в этом окне есть элемент выбора определенной папки для анализа (в этой папке есть другие папки с необходимыми файлами), так же в этом окошке есть графа где отображается общий результат суммы с названия файлов и кол-во обработанных файлов.

Если моя просьба реализуема - это просто замечательно. :smile:
P.S. И еще одна просьба - (если реализуем) то не могли бы Вы описать каждую строку кода, что она делает
(простите уж за наглость - оправдание у меня одно - жажда познать).
с ув.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
1. Из каталога нужно читать только файлы с расширением .cp или все файлы (не задеть бы видео-файлы :smile:), или нужно добавить выбор из заранее определенного списка расширений файлов с возможностью переключения?
2. Уточните как должны выглядеть удаляемые строки - опишите их уникальную маску что ли (какая часть строки всегда статична, а какая может меняться, вот так например: [abrrXuret] X - меняющееся число, остальное всегда статично), и их всегда именно две, и они всегда в конце?
3. Обработка предполагается только внутри определенного каталога или под-каталоги тоже обрабатывать?
4. Файл нужно переименовывать только если в нем проводились удаления или в любом случае?

Проясните эти вопросы и можно будет начать, задача не сложная.
 
Автор
Cfar

Cfar

Новичок
Сообщения
3
Репутация
0
Приветствую Redline
Спасибо за внимание.

1. Из каталога читать только файлы с расширением .cp
2. Строки статичны по виду и по положению(всегда в конце) и имеют вид:
...
G01X0.000Y0.000
M02

Строки находятся всегда в конце файла(но необходимо делать проверку на их наличие)
3. Обработка предполагается и в под-каталогах. (для примера: Есть папка с именем месяца, в ней папки с числами дней. Желательно выбрав только папку(месяц) - делать обработку файлов которые находятся во всех папках дней).
4. Файлы необходимо переименовывать в любом случае когда программа ее проверит(добавлять любой символ к имени файла - который будет показывать что этот файл был обработан для визуального восприятия человека и для самой программы, не проверять второй раз)

(файл .ср это текстовый файл управления для ЧПУ.. и последнии строки - это команда для возвращения каретки в нулевую позицию после порезки.. и т.к. это приводит к тому что каретка станка на скорости 30к метров в минуту радостно летит в ноль - немного незабываемо и раздражает :smile: )
с ув.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Поиск строк можно было сделать через чтение и сравнение FileReadLine, но мне привычнее через регулярные выражения.
Поиск в функциях осуществляется каждый раз заново, чтобы не исключить излишних телодвижений и заморочек с запоминанием "сканировали мы данный каталог или еще нет", если есть желание можете поковырять сами :smile:
Код:
#include <GUIConstants.au3>
#include <Array.au3>

$sFileType = '*.cp';расширения обрабатываемых файлов, через точку с запятой
$sSearch1 = 'G01X0.000Y0.000';искомые строки
$sSearch2 = 'M02'
$sSign = '#';строка для обозначения нового файла

$hGUI = GUICreate('Обработчик файлов *.cp', 640, 220);окно
$hInputPath = GUICtrlCreateInput('', 5, 5, 630, 21);поле для вывода пути к каталогу
GUICtrlSetState(-1, $GUI_DISABLE);поле делаем "только для чтения"
$hButtonOpenFolder = GUICtrlCreateButton('Выбрать папку', 480, 30, 150, 25);кнопка выбора каталога
$hButtonChek = GUICtrlCreateButton('Подсчитать', 10, 30, 120, 24);кнопка проверки файлов
$hButtonStart = GUICtrlCreateButton('Пуск', 250, 30, 80, 24);кнопка старта обратотки
$hLabelInfo = GUICtrlCreateLabel('', 10, 60, 620, 120)
$hProgress = GUICtrlCreateProgress(10, 190, 620, 15)
GUISetState(@SW_SHOW)

While 1
	$hMsg = GUIGetMsg();отлавливаем нажатия на кнопки
	Select
		Case $hMsg = $GUI_EVENT_CLOSE; закрытие окна программы
			Exit
		Case $hMsg = $hButtonOpenFolder; нажата кнопка вбора каталога
			$hFolder = FileSelectFolder('Выберите каталог для обработки', '', -1, @ScriptDir)
			If $hFolder <> '' Then	GUICtrlSetData($hInputPath, $hFolder);если пользователь не нажал отмену или не закрыл окно выбора каталога, то заносим полученный путь в поле ввода
		Case $hMsg = $hButtonStart; нажата кнопка пуска скрипта
			$sFolder = GUICtrlRead($hInputPath);читаем путь до каталога
			If $sFolder = '' Then;путь не был указан
				MsgBox(0, 'Ошибка', 'Не выбран каталог для обработки')
			ElseIf Not FileExists($sFolder) Then;такой каталог не существует
				MsgBox(0, 'Ошибка', 'Данного каталога не существует')
			Else
				$sOut = _processing($sFolder, $sSign);функция обработки файлов
				If Not @error Then
					GUICtrlSetData($hLabelInfo, 'Всего найдено и обработано файлов: ' & $sOut)
				Else
					MsgBox(0, 'Ничего не найдено', 'В данном каталоге не найдено ни одного подходящего файла')
				EndIf
			EndIf
		Case $hMsg = $hButtonChek; нажата кнопка проверки файлов
			$sFolder = GUICtrlRead($hInputPath);читаем путь до каталога
			If $sFolder = '' Then;путь не был указан
				MsgBox(0, 'Ошибка', 'Не выбран каталог для обработки')
			ElseIf Not FileExists($sFolder) Then;такой каталог не существует
				MsgBox(0, 'Ошибка', 'Данного каталога не существует')
			Else
				$aOut = _checkFiles($sFolder);функция анализа файлов
				If Not @error Then
					GUICtrlSetData($hLabelInfo, 'Всего найдено файлов: ' & $aOut[0] & @CRLF & 'полученная сумма: ' & $aOut[1])
				Else
					MsgBox(0, 'Ничего не найдено', 'В данном каталоге не найдено ни одного подходящего файла')
				EndIf
			EndIf
	EndSelect
WEnd

Func _checkFiles($sPath)
	$aFiles = _FileSearch($sPath, $sFileType); ищем файлы нужного расширения с выводом в массив
	If Not @error And $aFiles[0] > 0 Then; найден хотя бы один файл
		Local $iSumm = 0;здесь будем хранить сумму всех чисел, записанных в именах файлов
		For $i = 1 To $aFiles[0]
			$iSumm += Number(StringRegExpReplace($aFiles[$i], '^.*\\.*?\=(\d+).*', '$1'));от полного пути файла оставляем только цифры после знака равно, приводим его к числовому значению и сумируем
		Next
		Dim $aOut[2] = [$aFiles[0], $iSumm]
		Return $aOut
	Else;ничего не найдено
		SetError(1)
		Return 0
	EndIf
EndFunc

Func _processing($sPath, $sStr)
	$aFiles = _FileSearch($sPath, $sFileType); ищем файлы нужного расширения с выводом в массив
	If Not @error And $aFiles[0] > 0 Then; найден хотя бы один файл
		Dim $aNewNames[$aFiles[0] + 1][2];массив для хранения новых имен файлов
		$sPattern = '\Q' & $sSearch1 & '\E\v+\Q' & $sSearch2 & '\E$';шаблон для поиска искомых строк в конце файла
		For $i = 1 To $aFiles[0]
			GUICtrlSetData($hProgress, 100*(Round($i/$aFiles[0], 2)));двигаем прогресс
			GUICtrlSetData($hLabelInfo, 'Обрабатывается файл: ' & $aFiles[$i] & @CRLF & 'обрабатоно файлов: ' & $i & ' из ' & $aFiles[0])
			$aNewNames[$i][0] = StringRegExpReplace($aFiles[$i], '\\[^\\]*$', '');от полного пути файла оставляем только путь до файла
			$aNewNames[$i][1] = StringRegExpReplace($aFiles[$i], '^.*\\', '');от полного пути файла оставляем только имя и расширение
			$sFile = FileRead($aFiles[$i]);считываем файл
			If StringRegExp($sFile, $sPattern, 0) Then;в файле найдены искомые строки - удаляем
				$sNewFile = StringRegExpReplace($sFile, $sPattern, '');удаляем найденные строки в тексте
				$hFile = FileOpen($aFiles[$i], 2); открываем файл для перезаписи
				FileWrite($hFile, $sNewFile); пишем в файл
				FileClose($hFile);закрываем файл
			EndIf
			FileMove($aFiles[$i], $aNewNames[$i][0] & '\' & $sStr & $aNewNames[$i][1], 1); переименовываем обработанные файлы
		Next
		Return $aFiles[0]
	Else;ничего не найдено
		SetError(1)
		Return 0
	EndIf
EndFunc

Func _FileSearch($sPath, $sFileMask, $iSubDir = 1); функция поиска файлов (супер быстрая), есть на нашем форуме
	;первый параметр - путь, второй маска файлов для поиска, третий - флаг поиска в подкаталогах
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib
	If $iSubDir = 1 Then
		$sAttrib = ' /S /B /A'
	Else
		$sAttrib = ' /B /A'
	EndIf
	$sOut = StringToBinary('0' & @CRLF, 2)
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		$hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '"' & $sAttrib, @SystemDir, @SW_HIDE, 6)
		While 1
			$sRead = StdoutRead($hDir, False, True)
			If @error Then
				ExitLoop
			EndIf
			If $sRead <> '' Then
				$sOut &= $sRead
			EndIf
		WEnd
	Next
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Then
		Return SetError(1)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
Cfar

Cfar

Новичок
Сообщения
3
Репутация
0
Спасибо большое! :smile:
Времечко немного на работе появится - попробую в деле программу.
Насчет желания - его вагон..буду разбираться и учиться заодно :smile:
Спасибо еще раз за мой старт в AutoIt :beer:

Не удержался и решил по быстрому посмотреть.. в итоге:
строки не удаляются и в названии файла, при двойной проверке, дублируется знак "#".. т.е. два раза проверил в название два раза и добавило символ..
но все же, есть с чем работать :smile: , думаю разберусь
 
Верх