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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Копирование текста из другога файла в определённую строчку (http://forum.oszone.net/showthread.php?t=235521)

sweetpleasure 28-05-2012 13:42 1923881

Копирование текста из другога файла в определённую строчку
 
Здравствуйте.
Решила написать себе небольшой скрипт по работе с текстом, но не хватает знаний.
Код:

ssed.exe -e "4,703d" "D:\compilation\template\Web Site\Site.xml" > "D:\compilation\template\Web Site\output.xml"
del "D:\compilation\template\Web Site\Site.xml"
rename "D:\compilation\template\Web Site\output.xml" Site.xml

Удалить нужные строки получается, а вот как вставить новый текст не смогла найти информацию...
Как можно вставить многострочный текст (порядка 800 строк) из другого файла в известный номер строки?
Грубо говоря, взять один файл и перенести всё что там есть в другой файл в номер строки начиная с 4, при этом сместив текст в исходном, но не удаляя его.
Пример кода текста
HTML код:

<page>
      <name>index</name>
      <caption>Главная</caption>
      <pages />
      <content>
        <caption>Главная</caption>
        <title><![CDATA[Главная страница]]></title>
        <position>0</position>
        <dateCreated>0001-01-01T00:00:00</dateCreated>
        <dateModified>2012-04-06T16:36:11.25+03:00</dateModified>
        <description>0</description>
        <keywords>0</keywords>
        <titleInBrowser>Главная</titleInBrowser>
        <showInHmenu>true</showInHmenu>
        <showInVmenu>true</showInVmenu>
        <showTitle>false</showTitle>
      </content>
      <serverInfo>
        <title><![CDATA[]]></title>
        <position d5p1:nil="true" xmlns:d5p1="http://www.w3.org/2001/XMLSchema-instance" />
        <dateCreated>0001-01-01T00:00:00</dateCreated>
        <dateModified>0001-01-01T00:00:00</dateModified>
        <titleInBrowser />
        <showInHmenu>true</showInHmenu>
        <showInVmenu>true</showInVmenu>
        <showTitle>false</showTitle>
      </serverInfo>
</page>


Iska 28-05-2012 13:56 1923890

sweetpleasure, WSH Вам подойдёт?

Anonymоus 28-05-2012 13:57 1923891

Например, как-то так:
Код:

@Echo Off
SetLocal EnableDelayedExpansion

Set File1=source1.txt
Set File2=source2.txt
Set TargetLine=4
Set Output=out.txt

Set i=0
For /F "usebackq delims=" %%A In ("%File1%") Do (
        Set /A i+=1
        Echo.%%A>>"%Output%"
        If !i!==%TargetLine% (
                For /F "usebackq delims=" %%A In ("%File2%") Do (Echo.%%A>>"%Output%")
        )
)

После четвертой строки первого файла вставится построчно содержимое второго файла, а после - остаток первого. Недостатки - циклом For игнорируются пустые строки, из-за EnableDelayedExpansion игнорируются все восклицательные знаки в тексте.

sweetpleasure 28-05-2012 14:02 1923894

Цитата:

Цитата Anonymоus
После четвертой строки первого файла вставится построчно содержимое второго файла, а после - остаток первого. Недостатки - циклом For игнорируются пустые строки, из-за EnableDelayedExpansion игнорируются все восклицательные знаки в тексте.»

ой нет, восклицательные знаки там обязательны.

Цитата:

Цитата Iska
WSH Вам подойдёт? »

Подойдёт)

Я просто думала, что на ssed так же просто, как и удалить, можно вставить текст.

Iska 28-05-2012 15:12 1923929

Цитата:

Цитата sweetpleasure
Я просто думала, что на ssed так же просто, как и удалить, можно вставить текст. »

Может быть. Я с ним не работал.


Цитата:

Цитата sweetpleasure
Подойдёт) »

Попробуйте так:
читать дальше »
Код:

Option Explicit

Dim strSourceFile
Dim strDestFile
Dim lngInsertPosition

Dim objFSO

Dim strSourceContent
Dim strDestContent

Dim strTempFile
Dim strBackupFile

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If WScript.Arguments.Count <> 3 Then
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source file> <Destination file> <Line number for insert>"
        WScript.Quit 1
End If

With objFSO
        strSourceFile = WScript.Arguments.Item(0)
       
        If Not .FileExists(strSourceFile) Then
                WScript.Echo "Source file [" & strSourceFile & "] not found."
                WScript.Quit 2
        End If
       
        strDestFile = WScript.Arguments.Item(1)
       
        If Not .FileExists(strDestFile) Then
                WScript.Echo "Destination file [" & strDestFile & "] not found."
                WScript.Quit 3
        End If
       
        If Not IsNumeric(WScript.Arguments.Item(2)) Then
                WScript.Echo "Line number must be a numeric value."
                WScript.Quit 4
        End If
       
        lngInsertPosition = CLng(WScript.Arguments.Item(2))
       
        If lngInsertPosition < 0 Then
                WScript.Echo "Line number can't be less than zero."
                WScript.Quit 5
        End If
       
        With .OpenTextFile(strSourceFile)
                strSourceContent = .ReadAll()
                .Close
        End With
       
        With .OpenTextFile(strDestFile)
                strDestContent = ""
               
                Do Until .AtEndOfStream
                        If .Line <> lngInsertPosition Then
                                strDestContent = strDestContent & .ReadLine() & vbCrLf
                        Else
                                strDestContent = strDestContent & strSourceContent & .ReadLine() & vbCrLf
                        End If
                Loop
               
                .Close
        End With
       
        strTempFile = GetTemporaryName()
       
        With .CreateTextFile(strTempFile)
                .Write strDestContent
                .Close
        End With
       
        strBackupFile = .BuildPath(.GetParentFolderName(strDestFile), .GetBaseName(strDestFile) & ".bak")
       
        If .FileExists(strBackupFile) Then
                .DeleteFile strBackupFile
        End If
       
        .MoveFile strDestFile, strBackupFile
        .CopyFile strTempFile, strDestFile
        .DeleteFile strTempFile
End With

WScript.Quit
'=============================================================================

'=============================================================================
' Серый форум / vbscript: генерация пути для временного файла или папки
' (http://forum.script-coding.com/viewtopic.php?id=1221)
'=============================================================================
Function GetTemporaryName()
        Const TemporaryFolder = 2
       
        Dim strTempName
       
        With WScript.CreateObject("Scripting.FileSystemObject")
                Do
                        strTempName = .BuildPath(.GetSpecialFolder(TemporaryFolder), .GetTempName)
                Loop While .FileExists(strTempName) Or .FolderExists(strTempName)
        End With
       
        GetTemporaryName = strTempName
End Function
'=============================================================================


sweetpleasure 28-05-2012 15:24 1923937

А где можно задать номер строки, с которой начинать, а также файл с которого берём и куда вставляем?
Я образно сказала с 4... а так таких вставок будет несколько. Я просто продублирую скрипт.

Если я правильно поняла, то вот эта строка
Код:

WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source file> <Destination file> <Line number for insert>"
А в каком формате туда вставлять?

Так?
Код:

WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ "D:\compilation\template\Web Site\put.xml" "D:\compilation\template\Web Site\output.xml" 4"

Iska 28-05-2012 15:35 1923942

Запускаете командную строку, в ней пишете:
Код:

cscript.exe //nologo "<Путь\SomeScript.vbs" "Путь\Файл, содержимое которого надо вставить.xml>" "<Путь\Файл, в который надо вставить содержимое первого файла.xml>" <Номер строки, начиная с которой будет вставлено содержимое первого файла>
Например:
Код:

cscript.exe //nologo "c:\My Scripts\SomeScript.vbs" "C:\Песочница\0009\Source.xml" "C:\Песочница\0009\Destination.xml" 4
Для текущего каталога пути, разумеется, можно опускать.

P.S. Пример рассчитан на одну вставку за раз.

sweetpleasure 28-05-2012 15:51 1923952

Огромное спасибо!
А можно же вставлять в середину bat?
т.е. выполняется bat, доходит до строки
Код:

cscript.exe //nologo "c:\My Scripts\SomeScript.vbs" "C:\Песочница\0009\Source.xml" "C:\Песочница\0009\Destination.xml" 4
останавливается, выполняет скрипт, а после продолжает выполняться bat. Так ведь будет работать?

Iska 28-05-2012 17:03 1924012

sweetpleasure, можно. Работать будет.

sweetpleasure 28-05-2012 19:43 1924072

Всё отлично работает!
Я хотела бы ещё уточнить, возможно ли запустить bat, перетащив на него файл (drag and drop)?

Я использую
Код:

7z x *.zip -oD:\compilation\template
он работает, когда только файл zip рядом с bat-файлом...конечно можно прописать путь и тогда он начнёт работать из прописанной директории и при этом будет распаковывать все zip в этой директории. Можно прописать название zip, но архивы имеют разные имена.

Пробовала даже в Bat To Exe Converter делать exe, но всё равно не получается перетаскиванием нужного файла на ярлык запустить его обработку.

Если я верно понимаю, то нужно вместо * вставить какое-то значение, которое будет передаваться при перетаскивании объекта.

Нашла вот такой код, но не знаю насколько он эффективен
Код:

Suddenly the drag-drop has stopped working. How to fix this problem?

Click Start, Run and type these commands:

    cmd /c ftype batfile="%1" %*
    cmd /c assoc .bat=batfile
    regsvr32 /i shell32.dll

не решилась экспериментировать с shell32.dll

Anonymоus 28-05-2012 20:37 1924092

sweetpleasure, батник и так прекрасно распознает drag-n-drop, полный путь к файлу передается в переменной %1. Проблема в другом, батник стартует с рабочей директорией в профиле пользователя, что очень не удобно, если обвязка (архиватор, etc.) не прописана в Path.
В этом примере показано, как сменить рабочую директорию на ту, в которой находится батник, или ту, в которой находится перетягиваемый файл
Код:

@Echo Off
:: Рабочая директория. При drag-n-drop скрипт стартует с рабочей директорией
:: в %UserProfile%, что совсем не хорошо. Здесь можно выбрать, что будет являться
:: рабочей директорией: self - директория со скриптом, или target - директория с
:: перетягиваемым файлом
Set WorkDir=target

If Not "%~1"=="" (If %WorkDir%==target CD /D "%~dp1")
If Not "%~1"=="" (If %WorkDir%==self CD /D "%~dp0")

Echo Рабочая директория - [%CD%]
Echo Файл - [%~nx1]
Pause


sweetpleasure 28-05-2012 20:59 1924103

Понятно, вернее ничего не понятно)
А как это применить в моей ситуации?
Код:

@Echo Off
Set WorkDir=target

If Not "%~1"=="" (If %WorkDir%==target CD /D "%~dp1")
If Not "%~1"=="" (If %WorkDir%==self CD /D "%~dp0")

Echo Рабочая директория - [%CD%]
Echo Файл - [%~nx1]
Pause

7z x %~dp1 -oD:\compilation\template

Так получается? Я в этом вопросе новичок)

Anonymоus 28-05-2012 21:04 1924109

Цитата:

Цитата sweetpleasure
А как это применить в моей ситуации? »

Уточняющий вопрос - 7z.exe добавлен в %Path% или находится рядом со скриптом? Имеет ли значение, какая рабочая директория у батника?

sweetpleasure 28-05-2012 21:09 1924112

Цитата:

Цитата Anonymоus
Уточняющий вопрос - 7z.exe добавлен в %Path% или находится рядом со скриптом?»

7z я скачала специально для командной строки, поэтому он лежит рядом с бат-файлом.
Цитата:

Цитата Anonymоus
Имеет ли значение, какая рабочая директория у батника? »

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

Anonymоus 28-05-2012 21:14 1924118

Для варианта, когда 7z лежит рядом с батником
Код:

@Echo Off
CD /D "%~dp0"
7z x "%~1" -oD:\compilation\template


sweetpleasure 28-05-2012 21:18 1924122

Ураа) Заработало, большое спасибо!


Время: 06:47.

Время: 06:47.
© OSzone.net 2001-