arquivo em lote para encontrar uma palavra, extraia 2 linhas acima da palavra e escreva-a em um arquivo de texto diferente

0

No meu cenário, preciso verificar meu arquivo ( XXX.txt) para a palavra " SPOT ". Haverá poucas palavras do SPOT no arquivo.

Agora eu preciso de um script para escrever as 2 principais linhas da palavra " SPOT " em um novo texto fino e nomeá-lo como " done.txt".

EXEMPLO XXX.txt

dfsfs
clip_id HDX
title Setiap hari
type PROMO
end
clip_id HDQ
title Citra
type SPOT
end
clip_id HDX
title Ri
type PROMO
end
clip_id HDX
title sni
type SPOT

então eu preciso escrever " done.txt" como abaixo.

clip_id HDQ
title Citra

clip_id HDX
title sni

Por favor, informe o script para fazer isso.

Muito Obrigado

Poobalan
fonte
Bem-vindo ao superusuário. Infelizmente, não somos um serviço de codificação. Em vez de simplesmente pedir código para executar uma tarefa específica, mostre-nos o que você tentou até agora (incluindo qualquer código que você possui atualmente) e onde você está preso para que possamos ajudá-lo com seu problema específico. Perguntas que só pedem código são muito amplas e são susceptíveis de ser colocada em espera ou fechado
DavidPostill
Para uma .batsolução CLI pura , você pode começar comparando a saída do findstr /n /i "spot" "xxx.txt"comando e from findstr /n /R $ "xxx.txt"e, em seguida, tratá-la em dois FOR /F comandos de loop aninhado . Sinta-se à vontade para retornar aqui e editar sua pergunta seguindo a dica de comentário do @DavidPostill.
1911 JosefZ

Respostas:

0

Aqui está a solução em Powershell, sucessor de cmd da Microsoft:

# variables that you need to set
$source = "C:\temp\superuser.txt"
$destination = "C:\temp\done.txt"

#region easier to understand for PS newcomers
$hits = select-string -Path $source -SimpleMatch "SPOT" -CaseSensitive
$filecontents = get-content $source

foreach($hit in $hits)
{
    $filecontents[$hit.linenumber-3] | out-file -append $destination
    $filecontents[$hit.linenumber-2] | out-file -append $destination
    "" | out-file -append $destination
}
#endregion


#region shorter version
$hits = select-string -Path $file -SimpleMatch "SPOT" -CaseSensitive -context 2

foreach($hit in $hits)
{
    $hit.context.PreContext | out-file -append $destination
    "" | out-file -append $destination
}
#endregion
megamorf
fonte
oi megamorf te agradeço pela codificação. Mas devo salvar isso como arquivo .bat ou .ps1? Eu sou um novato e eu já vi qualquer saída, se executado como .bat ... por favor me esclareça .. muito obrigado!
Poobalan 19/03/2015
Salve o script como .ps1, Você pode executá-lo a partir do PowerShell, simplesmente digitando o caminho para o script ou executá-lo através de lote assim: ExecutionPolicy powershell desvio C: \ temp \ myscript.ps1
megamorf
Copyright do Windows PowerShell (C) 2009 Microsoft Corporation. Todos os direitos reservados. PS C: \ Users \ pmpooba \ Desktop \ SPOT COMMERCIAL> test4 O termo 'test4' não é reconhecido como o nome de um cmdlet, função, arquivo de script ou programa operável. Verifique a ortografia do nome ou, se um caminho foi incluído, verifique se o caminho está correto e tente novamente. Na linha: 1 char: 6 + test4 <<<< + CategoryInfo: ObjectNotFound: (test4: String) [], CommandNotFou ndException + FullyQualifiedErrorId: CommandNotFoundException PS C: \ Usuários \ pmpooba \ Desktop \ SPOT COMMERCIAL> ----- -> esta é a saída :(
Poobalan
Presumo que seu script se chama test4? Chame assim. \ Test4.ps1 O Powershell espera que você faça referência a scripts ou binários com sua extensão de arquivo e um caminho relativo ou absoluto por razões de segurança. Alguém poderia simplesmente colocar um test4.exe malicioso no mesmo diretório e seria chamado se essa medida de segurança não estivesse em vigor.
megamorf
sim, não pode ser executado porque alguma política de segurança ... pode salvar o mesmo script que .bat? se no..where i deve fazer alterações .... milhões de graças
Poobalan
0

Eu recomendo o JREPL.BAT - um utilitário JScript / lote híbrido que executa a substituição de texto de expressão regular . O JREPL.BAT é um script puro que roda nativamente em qualquer plataforma Windows a partir do XP.

Supondo que o JREPL.BAT esteja no seu diretório atual, ou melhor ainda, em algum lugar do seu PATH, um simples liner de linha de comando resolverá o problema com eficiência:

jrepl "^((.*\n){2})type SPOT$" $1 /m /jmatch /f xxx.txt /o done.txt
  • A /Mopção de múltiplas linhas permite pesquisas em novas linhas.
  • A /JMatchopção imprime apenas as cadeias de substituição para correspondências

Como JREPL é um script em lote, você deve usar CALL JREPL se usá-lo em outro script.

A documentação completa está disponível na linha de comando usando jrepl /?. Você pode usar jrepl /?|morepara ver a ajuda uma página de cada vez. Eu nunca uso MAIS porque minha janela do console do cmd.exe está configurada com um buffer de saída grande que me permite rolar para cima para ver a saída anterior.

dbenham
fonte
oi .. isso é o que eu fiz .. mas falhou .. @ eco no setlocal enabledelayedexpansion set src = C: \ Usuários \ pmpooba \ Desktop \ PGM \ xxx.txt defina dst = C: \ Users \ pmpooba \ Desktop \ PGM \ done.txt jrepl "^ ((. * \ n) {2}) digite SPOT $" $ 1 / m / jmatch / f% src% / o% dst%) pausa
Poobalan 27/03/15
Testei meu código e ele funciona. Você tem um extra )no final do comando JREPL que faz com que ele falhe. Além disso, você deve colocar CALL antes de JREPL se quiser que o script continue - caso contrário, seu comando PAUSE não será acionado.
dbenham