2

我有一个 bat 文件,我应该用它来删除一个文件的一部分并保存到另一个文件中。我需要删除文本“[aaa bbb]”和“[ccc ddd]”之间的所有符号。那就是如果我有文字:

[aaa bbb]
1
2
3
[ccc ddd]

我应该有输出:

[aaa bbb]
[ccc ddd]

谢谢

编辑:我想澄清这个问题。我应该删除marker1和marker2之间的所有符号。Marker1 和 marker2 只是一些单词或文本的一部分,而不是强制性的行。例如我会有:

[aaa bbb] [ccc]
1
2
3
4
5
[www yyy]

如果我想删除 [aaa bbb] 和 [www yyy] 之间的文本,我应该有输出:

[aaa bbb] 
[www yyy]
4

5 回答 5

2

查看此 sed 提示页面上的“在标记 1 和标记 2 之间删除”部分

将其应用于您的示例。clean.sed

/^\[aaa bbb\]$/,/^\[ccc ddd\]$/{
 /^\[aaa bbb\]$/!{
   /^\[ccc ddd\]$/!d
 }
}

运行使用:

sed -f clean.sed inputfile.txt

要“就地”编辑输入文件,请使用 sed 的 -i 选项:

sed -i.bak -f clean.sed datafile.txt

在编辑原始文件之前,会保存名为“datafile.txt.bak”的文件的备份副本。

编辑:由于假设标记总是在他们自己的一行上是错误的,这里有一个脚本可以处理一行中间的标记:

/\[aaa bbb\]/,/\[ccc ddd\]/{
  s/\[aaa bbb\].*/[aaa bbb]/
  s/.*\[ccc ddd\]/[ccc ddd]/
  /\[aaa bbb\]$/!{
    /^\[ccc ddd\]/!d
  }
}

对于此输入:

foo[aaa bbb]1
2
3
4
5[ccc ddd]bar
foo
[aaa bbb]
1
2
3
[ccc ddd]
bar

它产生:

foo[aaa bbb]
[ccc ddd]bar
foo
[aaa bbb]
[ccc ddd]
bar

笔记!无法处理标记可以出现在同一行的文件。

再次编辑:如果标记 1 的输入格式是这样的,你总是可以指望它在自己的一行上,你可以简化一些脚本:

/^\[aaa bbb\]$/,/\[ccc ddd\]/{
  s/.*\[ccc ddd\]/[ccc ddd]/
  /^\[aaa bbb\]$/!{
    /^\[ccc ddd\]/!d
  }
}

(将标记 1 锚定在一行的开头和结尾,并跳过标记 1 行的修剪。)

于 2009-01-08T21:04:45.970 回答
1

请注意,sed它可用于 Windows,以及一大堆其他 GNU 实用程序。我不确定您是否在问是否有等效的工具,或者一旦您获得了该工具,如何实际做到这一点。

于 2009-01-08T21:24:17.257 回答
1
D:\tmp\sed.exe -f sedscript.sed D:\tmp\test.txt >c:\tmp\test2.txt


/^\[产品特点\]$/,/^\[Dm$/{
 /^\[产品特点\]$/!{
 /^\[Dm$/!d
 }
 }
于 2009-01-08T21:51:46.063 回答
0

我查看了 cmd 和 power shell - 找不到任何有用的东西。让自己成为 ActivePerl?

于 2009-01-08T21:04:13.680 回答
0

如果您信任此答案的“类似sed”的VB脚本...

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

您可以输入
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt(in.txt 是您的初始文本)

您将获得预期的输出...

^\d+\s*$

将针对以一个或多个数字开头的任何行,然后一行中的 0 个或多个空格。


这不是最好的“纯 sed”解决方案,它实际上不能删除行,但这是一个原生的“符合 vista”的解决方案......


实际上,以下故意解释“ dsed-command”的黑客可以“删除”行:

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实际上会产生:

[aaa bbb]
[ccc ddd]

在 .bat 中,您可以有一个 sed.bat:

cscript /Nologo sed.vbs %1 < %2

然后像这样执行那个.bat:

C:\prog\sed>sed.bat s/^\d+\s*$/d in.txt
于 2009-01-08T21:04:31.900 回答