2

あるファイルの一部を削除して別のファイルに保存するために使用するバットファイルがあります。テキスト「[aaa bbb]」と「[ccc ddd]」の間のすべての記号を削除する必要があります。それは私がテキストを持っている場合です:

[aaa bbb]
1
2
3
[ccc ddd]

私は出力として持っている必要があります:

[aaa bbb]
[ccc ddd]

ありがとうございました

編集:質問を明確にしたいと思います。マーカー 1 とマーカー 2 の間のすべてのシンボルを削除する必要があります。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

入力ファイルを「その場で」編集するには、-i オプションを使用して sed を実行します。

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

sedWindows で利用できることに注意してください他の 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

この回答のVBスクリプト「sed-like」を信頼する場合...

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*$

1 つ以上の数字で始まり、1 行内に 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 に答える