Reputation: 5224
I have a bat file that I should use to delete a part of one file and save into another one. I need to delete all the symbols between text "[aaa bbb]" and "[ccc ddd]". That is if I have the text:
[aaa bbb]
1
2
3
[ccc ddd]
I should have as output:
[aaa bbb]
[ccc ddd]
Thank you
EDIT: I would like to clarify the question. I should delete all the symbols between marker1 and marker2. Marker1 and marker2 are just some words or parts of text but not obligatory lines. For example I would have:
[aaa bbb] [ccc]
1
2
3
4
5
[www yyy]
If I want to delete the text between [aaa bbb] and [www yyy] I should have as output:
[aaa bbb]
[www yyy]
Upvotes: 2
Views: 1433
Reputation: 17004
Take a look at the section "Delete between marker 1 and marker2" on this sed hints page
Applying it on your example. clean.sed:
/^\[aaa bbb\]$/,/^\[ccc ddd\]$/{
/^\[aaa bbb\]$/!{
/^\[ccc ddd\]$/!d
}
}
Run using:
sed -f clean.sed inputfile.txt
To edit the input file "in place", use the -i option to sed:
sed -i.bak -f clean.sed datafile.txt
A backup copy of the file with the name "datafile.txt.bak" is saved before editing the original.
EDIT: Since the assumption that the markers where always on a line of their own was wrong, heres a script that can handle markers in the middle of a line:
/\[aaa bbb\]/,/\[ccc ddd\]/{
s/\[aaa bbb\].*/[aaa bbb]/
s/.*\[ccc ddd\]/[ccc ddd]/
/\[aaa bbb\]$/!{
/^\[ccc ddd\]/!d
}
}
For this input:
foo[aaa bbb]1
2
3
4
5[ccc ddd]bar
foo
[aaa bbb]
1
2
3
[ccc ddd]
bar
It produces:
foo[aaa bbb]
[ccc ddd]bar
foo
[aaa bbb]
[ccc ddd]
bar
Note! It can't handle files where the markers can appear on the same line.
EDIT again: If the input format for marker 1 is such that you can always count on it being on a line of its own you can simplify the script some:
/^\[aaa bbb\]$/,/\[ccc ddd\]/{
s/.*\[ccc ddd\]/[ccc ddd]/
/^\[aaa bbb\]$/!{
/^\[ccc ddd\]/!d
}
}
(Anchoring marker 1 at the beginning and end of a line and skipping the trimming of the marker 1 line.)
Upvotes: 2
Reputation: 5224
D:\tmp\sed.exe -f sedscript.sed D:\tmp\test.txt >c:\tmp\test2.txt /^\[Product Feature\]$/,/^\[Dm$/{ /^\[Product Feature\]$/!{ /^\[Dm$/!d } }
Upvotes: 1
Reputation: 48369
Note that sed
is available for Windows, along with a whole bunch of other GNU utilities. I'm not sure if you're asking whether there's an equivalent, or how to actually do it once you've got the tool.
Upvotes: 1
Reputation: 1323333
If you trust the VB script "sed-like" of this answer...
sed.vbs:
Dim pat, patparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
inp = WScript.StdIn.ReadLine()
WScript.Echo rxp.Replace(inp, patparts(2))
Loop
You can type
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt
(in.txt being your initial text)
and you will obtain the expected output...
^\d+\s*$
Would target any line beginning with one or more digit, followed by 0 or more spaces within one line.
That is not the best "pure sed" solution and it can not actually delete lines, but this is a native "vista-compliant" solution...
Actually, the following hack deliberately interpreting the "d
sed-command" could be able to 'delete' lines:
Dim pat, patparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
inp = WScript.StdIn.ReadLine()
out = rxp.Replace(inp, patparts(2))
if not patparts(2)="d" or not out="d" Then
WScript.Echo out
end if
Loop
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt
would actually produce:
[aaa bbb]
[ccc ddd]
In a .bat, you could have a sed.bat:
cscript /Nologo sed.vbs %1 < %2
and then execute that .bat like this:
C:\prog\sed>sed.bat s/^\d+\s*$/d in.txt
Upvotes: 0
Reputation:
I looked at cmd and at power shell - can't find anything useful. Get yourself ActivePerl?
Upvotes: 0