Войти

Показать полную графическую версию : [решено] Копирование текста из другога файла в определённую строчку


sweetpleasure
28-05-2012, 13:42
Здравствуйте.
Решила написать себе небольшой скрипт по работе с текстом, но не хватает знаний.
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, при этом сместив текст в исходном, но не удаляя его.
Пример кода текста
<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
sweetpleasure, WSH Вам подойдёт?

Anonymоus
28-05-2012, 13:57
Например, как-то так:

@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
После четвертой строки первого файла вставится построчно содержимое второго файла, а после - остаток первого. Недостатки - циклом For игнорируются пустые строки, из-за EnableDelayedExpansion игнорируются все восклицательные знаки в тексте.»
ой нет, восклицательные знаки там обязательны.

WSH Вам подойдёт? »
Подойдёт)

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

Iska
28-05-2012, 15:12
Я просто думала, что на ssed так же просто, как и удалить, можно вставить текст. »
Может быть. Я с ним не работал.

Подойдёт) »
Попробуйте так:
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
А где можно задать номер строки, с которой начинать, а также файл с которого берём и куда вставляем?
Я образно сказала с 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
Запускаете командную строку, в ней пишете:
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
Огромное спасибо!
А можно же вставлять в середину 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
sweetpleasure, можно. Работать будет.

sweetpleasure
28-05-2012, 19:43
Всё отлично работает!
Я хотела бы ещё уточнить, возможно ли запустить 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
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
Понятно, вернее ничего не понятно)
А как это применить в моей ситуации?
@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
А как это применить в моей ситуации? »
Уточняющий вопрос - 7z.exe добавлен в %Path% или находится рядом со скриптом? Имеет ли значение, какая рабочая директория у батника?

sweetpleasure
28-05-2012, 21:09
Уточняющий вопрос - 7z.exe добавлен в %Path% или находится рядом со скриптом?»
7z я скачала специально для командной строки, поэтому он лежит рядом с бат-файлом.
Имеет ли значение, какая рабочая директория у батника? »
Не совсем поняла вопрос.. что вы имеете ввиду под рабочей директорией?

Anonymоus
28-05-2012, 21:14
Для варианта, когда 7z лежит рядом с батником

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

sweetpleasure
28-05-2012, 21:18
Ураа) Заработало, большое спасибо!




© OSzone.net 2001-2012