Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   открыть файл-архив, используя 7-ZIP, изменить текст и закрыть файл,сохранив изменения (http://forum.oszone.net/showthread.php?t=341846)

v79italya 17-08-2019 19:08 2884474

открыть файл-архив, используя 7-ZIP, изменить текст и закрыть файл,сохранив изменения
 
Приветствую. как можно JS-скриптом или Batом открыть файл-архив, используя 7-ZIP, изменить текст и закрыть файл,сохранив изменения?
на скринах показаны шаги. архив открывается двумя шагами. сначала ПКМ -> 7-Zip -> Открыть архив. затем ПКМ -> Просмотр. нажав Просмотр, жду около минуты(это, наверное, надо учесть, поставив как то паузу) открытие файла. когда файл откроется, нажимаю Правка -> Найти.. ищу </xyzID> . все вместе <xyzID>3</xyzID> . только вместо тройки может быть любое число одно-трехзначное. и вот вместо 3(или другого числа) надо поставить 27. причем, когда набираю 27, то опять нужно около минуты ждать(опять надо учесть). потом закрываю файл с сохранением изменений и обновлением файла в архиве. возможно ли это все делать на автомате?
адрес файла и имя файла, наверное, лучше в скрипте указать. сейчас так: C:\red\xyz.iwprj2
сейчас в файле текст укорочен. поэтому будет быстро сохраняться изменения. на самом деле надо около минуты-полторы.

Iska 17-08-2019 20:11 2884490

v79italya, можно, но совсем не так, как Вы себе это представляете.

Исходные данные:
  1. Знаем точное местоположение файла архива.
  2. Знаем точное местоположение искомого файла в архиве.
  3. Знаем, что потребно искать.
  4. Знаем, какой архиватор будем пользовать, и предполагаем, что он может быть установлен по стандартному месторасположению.

Процесс:
  1. Проверяем существование файла архива.
  2. Проверяем существование архиватора.
  3. Проверяем существование искомого файла в архиве.
  4. Извлекаем искомый файл из архива во временный каталог.
  5. Читаем содержимое искомого файла, осуществляем поиск и замену.
  6. Если поиск был успешен — сохраняем новое содержимое в искомый файл, помещаем искомый файл в архив с заменой, удаляем временный каталог с файлом.
Поместите в gzip-архив весь искомый файл целиком.

greg zakharov 17-08-2019 20:51 2884500

Iska, все это второстепенные категории, да и пункты с четвертого по шестой уж больно притянуты за уши в случае с 7zip. Объясню почему. У данного архиватора предусмотрена возможность вывода в поток (ровно как и чтение из потока). Используя sed в качестве потокового редактора, можно запросто редактировать, скажем, текстовые файлы в архиве без извлечения во временную папку. Представьте, есть у нас некоторый текстовый файл some.txt:
Код:

regular string
obsolete
regular string

Жмем его, скажем в zip:
Код:

7za a -mx9 test.zip some.txt
Теперь представим, что в только что пожатом текстовом файле нужно obsolete заменить на new string. Как мы поступаем:
Код:

7za x test.zip -so | sed "s/obsolete/new string/Ig" | 7za u test.zip -si
7za d test.zip some.txt
7za rn test.zip test some.txt

Это, конечно, всего лишь схематичный порядок действий, чтобы был ясен сам принцип. Доработать пример напильником можно углубившись в справку 7zip.

v79italya 18-08-2019 06:51 2884531

Цитата:

Цитата Iska
1. Знаем
2. Знаем
3. Знаем
4. Знаем »

так я уже написал:
1 - C:\red\ или C:\red\xyz.iwprj2
2 - он там один xyz
3 - xyzID>3</xyzID> , но вместо тройки может быть любое число
4 - C:\Program Files\7-Zip\7z.exe
попробуйте распаковать архив на диск С: . на скринах показано как я делаю это вручную. и хотелось бы также программно.
greg zakharov, а нельзя ли готовое решение?

Iska 18-08-2019 13:59 2884567

greg zakharov, это всё, конечно, интересно, но имеет достаточно ограниченную область применения. Как там с кодировками, BOM, концами строк, а?

Цитата:

Цитата v79italya
попробуйте распаковать архив на диск С: . »

Попробуйте выложить архив с полным содержимым xml-файла xyz.

Цитата:

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

Я уже написал, что «так же» программно не получится. Как — тоже написал. Другой вариант предложил коллега greg zakharov.

Busla 18-08-2019 14:23 2884571

greg zakharov, 7zip в поток выводит только потоковые форматы, традиционные .zip, .rar, .7z к ним не относятся. Да и sed я бы не стал советовать - стороннее ПО, да и "вещь в себе" - лучше на PoSh сварганить замену.

Цитата:

Цитата Iska
Процесс:
Проверяем существование файла архива.
Проверяем существование архиватора.
Проверяем существование искомого файла в архиве. »

Таких пунктов можно бесконечное число навертеть.
Если их убрать ничего не изменится - о проблеме ОС/интерпретатор сообщит, а "результат" будет тот же.

Iska 18-08-2019 15:04 2884576

Цитата:

Цитата Busla
7zip в поток выводит только потоковые форматы, традиционные .zip, .rar, .7z к ним не относятся. »

Поясните?!

Цитата:

Цитата Busla
Если их убрать ничего не изменится - о проблеме ОС/интерпретатор сообщит, а "результат" будет тот же. »

Можно, конечно, и так. Но лучше заранее обрабатывать такие ситуации.

v79italya 18-08-2019 15:04 2884577

Цитата:

Цитата Iska
архив с полным содержимым xml-файла »

написал Вам в личку.
а там:
Iska превысил(а) максимальный объем сохраненных персональных сообщений и не может получать новые сообщения, пока не удалит часть старых.

Iska 18-08-2019 15:12 2884582

Цитата:

Цитата v79italya
написал Вам в личку. »

Там что-то секретное, что ли, и Вы не хотите сие «светить»? Ну, пришлите на почту.

v79italya 18-08-2019 15:29 2884586

Iska, и со второго раза не получилось отправить в личку, а на маил не предусмотрено прикрепление файл.
в принципе то же самое, только текста больше. можно и обойтись

Iska 18-08-2019 15:34 2884588

Цитата:

Цитата v79italya
а на маил не предусмотрено прикрепление файл. »

Отправьте тестовое письмо с адресом, я Вам отвечу, затем Вы сможете написать напрямую. Сам я не могу Вам отправить письмо по причине:
Цитата:

Извините, этот пользователь отключил прием E-mail.

v79italya 18-08-2019 15:48 2884590

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

Iska 18-08-2019 15:59 2884593

Цитата:

Цитата v79italya
не получается отправить тестовое письмо. »

Мне уже две штуки пришло, и я Вам на них ответил.

Цитата:

Цитата v79italya
давайте использовать файл из темы. »

Тогда без меня. Я предпочитаю работать с xml-файлом, как с xml-файлом, а не с его огрызком.

v79italya 18-08-2019 16:05 2884595

Iska, отправил оригинал

Busla 18-08-2019 17:24 2884607

Цитата:

Цитата Iska
Цитата Busla:
7zip в поток выводит только потоковые форматы, традиционные .zip, .rar, .7z к ним не относятся. »
Поясните?! »

алгоритм разработан так что получает поток и отдаёт поток - последовательность данных в один проход
для них возможно выдавать в stdout
Цитата:

If the -so switch is used with the command that creates archive, it works only with some archive formats: xz, gzip, bzip2 and tar.
Цитата:

Цитата Iska
Если их убрать ничего не изменится - о проблеме ОС/интерпретатор сообщит, а "результат" будет тот же. »
Можно, конечно, и так. Но лучше заранее обрабатывать такие ситуации. »

"обработать ситуацию" - это если не нашёлся 7zip, поискать WinRar

а ваша обработка в стиле вместо ошибки (с ошибочным кодом возврата) написать красный текст с нормальным кодом завершения - это медвежья услуга

greg zakharov 18-08-2019 18:27 2884617

Цитата:

Цитата Iska
Как там с кодировками, BOM, концами строк, а?

Нормально. А должно быть иначе?
Цитата:

Цитата Busla
7zip в поток выводит только потоковые форматы, традиционные .zip, .rar, .7z к ним не относятся.

Очередной бред? Или вдруг из исходников собрался какой-то специфический 7zip? Для начала бы просто проверили -so и -si на практике.
Цитата:

Цитата Busla
Да и sed я бы не стал советовать - стороннее ПО, да и "вещь в себе" - лучше на PoSh сварганить замену.

Ага... А 7zip не стороннее ПО? На pwsh можно много чего сделать. Однако в вашем случае это обычное пустословие, ибо, во-первых, вы бы привели рабочий код, во-вторых, случись RAR формат вы бы наверняка использовали сторонние библиотеки. Или вы желаете заложиться на почку, что можете на pwsh реализовать алгоритм сжатия RAR?

Sham 18-08-2019 20:58 2884640

С sed'ом работает и bom-метку сохраняет, но через временный файл только
Код:

7z x -tgzip xyz.iwprj2 -so | sed "s/\(<xyzID>\)[0-9]\{1,\}\(<\/xyzID>\)/\127\2/ig" >tempfile.tmp & 7z u -tgzip xyz.iwprj2 -sixyz <tempfile.tmp & del /f tempfile.tmp

Busla 18-08-2019 22:56 2884657

Цитата:

Цитата greg zakharov
Очередной бред? Или вдруг из исходников собрался какой-то специфический 7zip? Для начала бы просто проверили -so и -si на практике. »

бред - это проверять на практике то, что по инструкции работать не должно
даже если в вашем случае это сработало - это называется deprecated - не нужно ориентироваться на такое поведение, чтобы потом не было больно

greg zakharov 19-08-2019 00:08 2884663

Цитата:

Цитата Busla
бред - это проверять на практике то, что по инструкции работать не должно
даже если в вашем случае это сработало - это называется deprecated - не нужно ориентироваться на такое поведение, чтобы потом не было больно

Бред нарастает. Где в манах 7zip написано что это устаревшая фича? То у вас sed чуть ли не от лукавого, то попытки оправдать свой бред...

Busla 19-08-2019 10:57 2884699

Цитата:

Цитата greg zakharov
Бред нарастает. Где в манах 7zip написано что это устаревшая фича? »

"Сама придумала, сама обиделась"
где я писал про устаревшую фичу? :o

Я привёл конкретную цитату из инструкции к последнему стабильному релизу.

Цитата:

Цитата greg zakharov
Ага... А 7zip не стороннее ПО? »

ваша аналогия неуместна - 7zip (или другой архиватор) для решения задачи необходим, а sed - нет
ну и где брать архиватор - понятно, а где брать sed - нет

Iska 19-08-2019 17:41 2884747

v79italya, пробуйте (на PowerShell):
Скрытый текст
Код:

$sArchiveFile    = 'C:\Мои проекты\0272\project.iwprj2'
$sSourceFileName = 'project'
$sPath27Za      = "$($env:ProgramFiles)\7-Zip\7za.exe"

if([System.IO.File]::Exists($sArchiveFile)) {
    if([System.IO.File]::Exists($sPath27Za)) {
        $oProcess = New-Object -TypeName 'System.Diagnostics.Process'

        $oProcess.StartInfo.FileName              = $sPath27Za
        $oProcess.StartInfo.Arguments              = "e -y -sccWIN -o""$($env:TEMP)"" ""$sArchiveFile"" ""$sSourceFileName"""
        $oProcess.StartInfo.CreateNoWindow        = $true
        $oProcess.StartInfo.UseShellExecute        = $false
        $oProcess.StartInfo.RedirectStandardOutput = $true

        if($oProcess.Start()) {
            Write-Host "Trying extract source file [$sSourceFileName] from archive [$sArchiveFile] into temp folder [$($env:TEMP)]." -ForegroundColor Green
            $oProcess.WaitForExit()
            Write-Host $($oProcess.StandardOutput.ReadToEnd()) -ForegroundColor Cyan

            if($oProcess.ExitCode -eq 0) {
                $sTempFile = "$($env:TEMP)\$sSourceFileName"
                Write-Host "Trying find and replace value in extracted file [$sTempFile]." -ForegroundColor Green

                try {
                    $oXmlDocument = [System.Xml.XmlDocument](Get-Content -Path $sTempFile)
                    $oXmlDocument.StateOfInfoProject.CaptchaID = '27'
                    $oXmlDocument.Save($sTempFile)
                } catch {
                    Write-Host "Can't find and replace value in extracted file [$sTempFile]." -ForegroundColor Red
                }

                $oProcess.StartInfo.Arguments = "u -y -sccWIN ""$sArchiveFile"" ""$sTempFile"""

                if($oProcess.Start()) {
                    Write-Host "Trying update source file [$sSourceFileName] in archive [$sArchiveFile] from previously extracted file [$sTempFile]." -ForegroundColor Green
                    $oProcess.WaitForExit()
                    Write-Host $($oProcess.StandardOutput.ReadToEnd()) -ForegroundColor Cyan

                    if($oProcess.ExitCode -eq 0) {
                        Write-Host "Delete temporary file [$sTempFile]." -ForegroundColor Green
                        [System.IO.File]::Delete($sTempFile)
                    } else {
                        Write-Host "Can't update file [$sSourceFileName] in archive [$sArchiveFile] from file [$sTempFile] correctly. 7za.exe return non-zero exit code: $($oProcess.ExitCode)." -ForegroundColor Red
                    }
                } else {
                    Write-Host "Can't execute [$($oProcess.StartInfo.FileName)] with arguments [$($oProcess.StartInfo.Arguments)] normally." -ForegroundColor Red
                }
            } else {
                Write-Host "Can't extract source file [$sSourceFileName] from archive [$sArchiveFile] correctly. 7za.exe return non-zero exit code: $($oProcess.ExitCode)." -ForegroundColor Red
            }
        } else {
            Write-Host "Can't execute [$($oProcess.StartInfo.FileName)] with arguments [$($oProcess.StartInfo.Arguments)] normally." -ForegroundColor Red
        }
    } else {
        Write-Host "Can't find executable file [$sPath27Za]." -ForegroundColor Red
    }
} else {
    Write-Host "Can't find archive file [$sArchiveFile]." -ForegroundColor Red
}


Цитата:

Цитата Busla
алгоритм разработан так что получает поток и отдаёт поток - последовательность данных в один проход
для них возможно выдавать в stdout
Цитата:

If the -so switch is used with the command that creates archive, it works only with some archive formats: xz, gzip, bzip2 and tar.
»

Busla, спасибо, ясно. Ну, в данном случае как раз таки gzip.

Цитата:

Цитата Busla
"обработать ситуацию" - это если не нашёлся 7zip, поискать WinRar »

Не могу с Вами согласиться, коллега.

Цитата:

Цитата Busla
а ваша обработка в стиле вместо ошибки (с ошибочным кодом возврата) написать красный текст с нормальным кодом завершения - это медвежья услуга »

Это правильно, но меня дико бесит отлаживать такие ситуации в ISE — понимаете, почему. А писать красным текстом я перестану не раньше, чем этим перестанет заниматься Microsoft.

Цитата:

Цитата greg zakharov
Нормально. А должно быть иначе? »

Раз у Вас нормально, значит, проблемы на моей стороне.

Цитата:

Цитата Sham
С sed'ом работает и bom-метку сохраняет, но через временный файл только »

А у меня и напрямую код коллеги greg zakharov отработал. Про метку BOM — что б ему не сохранять? Вот с UTF-16LE/1200 с BOM — там интереснее должно получиться. Я особо не ковырял.

v79italya 20-08-2019 06:26 2884803

Iska, Ваш код работает! работает просто сказка! еще работает пол-секунды. и не поймешь - запустился или не запустился скрипт. проверяю файл - есть изменения. все супер. Спасибо Вам большое!
Sham, Ваш код не знаю как запустить. какой программой? я про Power Shell пол-часа гуглил перед запуском. так то, вопрос решен.

Iska 20-08-2019 09:52 2884816

Цитата:

Цитата v79italya
и не поймешь - запустился или не запустился скрипт. »

Ну, давайте чуть поменяем:
Скрытый текст
Код:

$sArchiveFile    = 'C:\Мои проекты\0272\project.iwprj2'
$sSourceFileName = 'project'
$sPath27Za      = "$($env:ProgramFiles)\7-Zip\7za.exe"

if([System.IO.File]::Exists($sArchiveFile)) {
    if([System.IO.File]::Exists($sPath27Za)) {
        $oProcess = New-Object -TypeName 'System.Diagnostics.Process'

        $oProcess.StartInfo.FileName              = $sPath27Za
        $oProcess.StartInfo.Arguments              = "e -y -sccDOS -o""$($env:TEMP)"" ""$sArchiveFile"" ""$sSourceFileName"""
        $oProcess.StartInfo.CreateNoWindow        = $true
        $oProcess.StartInfo.UseShellExecute        = $false
        $oProcess.StartInfo.RedirectStandardOutput = $true

        if($oProcess.Start()) {
            Write-Host "Trying extract source file [$sSourceFileName] from archive [$sArchiveFile] into temp folder [$($env:TEMP)]." -ForegroundColor Green
            $oProcess.WaitForExit()
            Write-Host $($oProcess.StandardOutput.ReadToEnd()) -ForegroundColor Cyan

            if($oProcess.ExitCode -eq 0) {
                $sTempFile = "$($env:TEMP)\$sSourceFileName"
                Write-Host "Trying find and replace value in extracted file [$sTempFile]." -ForegroundColor Green

                try {
                    $oXmlDocument = [System.Xml.XmlDocument](Get-Content -Path $sTempFile)
                    $oXmlDocument.StateOfInfoProject.CaptchaID = '27'
                    $oXmlDocument.Save($sTempFile)
                } catch {
                    Write-Host "Can't find and replace value in extracted file [$sTempFile]." -ForegroundColor Red
                }

                $oProcess.StartInfo.Arguments = "u -y -sccDOS ""$sArchiveFile"" ""$sTempFile"""

                if($oProcess.Start()) {
                    Write-Host "Trying update source file [$sSourceFileName] in archive [$sArchiveFile] from previously extracted file [$sTempFile]." -ForegroundColor Green
                    $oProcess.WaitForExit()
                    Write-Host $($oProcess.StandardOutput.ReadToEnd()) -ForegroundColor Cyan

                    if($oProcess.ExitCode -eq 0) {
                        Write-Host "Delete temporary file [$sTempFile]." -ForegroundColor Green
                        [System.IO.File]::Delete($sTempFile)
                    } else {
                        Write-Host "Can't update file [$sSourceFileName] in archive [$sArchiveFile] from file [$sTempFile] correctly. 7za.exe return non-zero exit code: $($oProcess.ExitCode)." -ForegroundColor Red
                    }
                } else {
                    Write-Host "Can't execute [$($oProcess.StartInfo.FileName)] with arguments [$($oProcess.StartInfo.Arguments)] normally." -ForegroundColor Red
                }
            } else {
                Write-Host "Can't extract source file [$sSourceFileName] from archive [$sArchiveFile] correctly. 7za.exe return non-zero exit code: $($oProcess.ExitCode)." -ForegroundColor Red
            }
        } else {
            Write-Host "Can't execute [$($oProcess.StartInfo.FileName)] with arguments [$($oProcess.StartInfo.Arguments)] normally." -ForegroundColor Red
        }
    } else {
        Write-Host "Can't find executable file [$sPath27Za]." -ForegroundColor Red
    }
} else {
    Write-Host "Can't find archive file [$sArchiveFile]." -ForegroundColor Red
}

Write-Host 'Press any key to continue...'
[void][System.Console]::ReadKey($true)


v79italya 20-08-2019 16:27 2884835

Цитата:

Цитата Iska
не поймешь - запустился или не запустился скрипт »

так это по началу так. когда открывал Power Shell и вставлял код в программу и запускал.
а потом я сохранил в файл.ps1 и все. запускаю ПКМ Выполнить с помощью PowerShell, появляется окно cmd и как закроется, значить, скрипт сработал.
Iska, ничего менять не буду. все отлично. спасибо Вам

Iska 20-08-2019 16:39 2884838

Цитата:

Цитата v79italya
появляется окно cmd »

Неа. Не «окно cmd». Появляется окно консоли PowerShell.

Цитата:

Цитата v79italya
Iska, ничего менять не буду. все отлично. »

Если что-то пойдёт не так — поменяйте, хоть прочитать можно будет, что именно идёт не так.

v79italya 20-08-2019 19:20 2884854

Цитата:

Цитата Iska
пойдёт не так — поменяйте »

ok


Время: 08:33.

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