Pergunta

Eu tenho um arquivo bat que eu deveria usar para excluir uma parte de um arquivo e salvar em outro. Eu preciso eliminar todos os símbolos entre o texto "[aaa bbb]" e "[ccc ddd]". Isto é, se eu tenho o texto:

[aaa bbb]
1
2
3
[ccc ddd]

Eu deveria ter como saída:

[aaa bbb]
[ccc ddd]

Obrigado

EDIT: Eu gostaria de esclarecer a questão. I deve eliminar todos os símbolos entre marker1 e marker2. Marker1 e marker2 são apenas algumas palavras ou partes de texto, mas não linhas obrigatórias. Por exemplo, eu teria:

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

Se eu quiser excluir o texto entre [aaa bbb] e [yyy www] Eu deveria ter como saída:

[aaa bbb] 
[www yyy]
Foi útil?

Solução

Dê uma olhada na seção "Excluir entre o marcador 1 e marker2" na desta página dicas sed

aplicá-lo sobre o seu exemplo. clean.sed :

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

Executar usando:

sed -f clean.sed inputfile.txt

Para editar o arquivo de entrada "no lugar", use a opção -i para sed:

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

A cópia de backup do arquivo com o nome "datafile.txt.bak" é salvo antes de editar o original.

EDIT: Desde a suposição de que os marcadores onde sempre em uma linha da sua própria estava errado, aqui está um script que pode lidar com marcadores no meio de uma linha:

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

Para esta entrada:

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

Ela produz:

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

Nota! não pode arquivos punho, onde os marcadores podem aparecer na mesma linha.

EDIT novamente: Se o formato de entrada para o marcador 1 é tal que você pode sempre contar com ele estar em uma linha própria você pode simplificar o script alguns:

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

(marcador de ancoragem 1 no início e fim de uma linha e ignorando o aparamento da linha de marcação 1.)

Outras dicas

Note que sed está disponível para Windows, juntamente com um conjunto grupo de outros utilitários GNU. Eu não tenho certeza se você está perguntando se há um equivalente, ou como realmente fazê-lo uma vez que você tem a ferramenta.

D:\tmp\sed.exe -f sedscript.sed D:\tmp\test.txt >c:\tmp\test2.txt


/^\[Product Feature\]$/,/^\[Dm$/{
 /^\[Product Feature\]$/!{
 /^\[Dm$/!d 
 }
 } 

Eu olhei para cmd e no shell de energia - não consigo encontrar nada útil. Arranja ActivePerl?

Se você confiar no script VB "sed-like" do esta resposta ...

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

Você pode digitar
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt (in.txt sendo o seu texto inicial)

e você vai obter o resultado esperado ...

^\d+\s*$

teria como alvo qualquer linha que começa com um ou mais dígitos, seguido por 0 ou mais espaços dentro de uma linha.


Essa não é a melhor solução "pura sed" e pode linhas na verdade não apagar, mas esta é uma solução nativa "vista-compliant" ...


Na verdade, o seguinte truque deliberadamente interpretar o "d sed-comando" poderia ser capaz de linhas 'apagar':

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 seria realmente produzir:

[aaa bbb]
[ccc ddd]

Em um .bat, você poderia ter um sed.bat:

cscript /Nologo sed.vbs %1 < %2

e, em seguida, executar esse .bat como esta:

C:\prog\sed>sed.bat s/^\d+\s*$/d in.txt
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top