Arquivo de lote do Windows - exclui dados após um delimitador

0

Eu tenho visto vários exemplos do que preciso e tentei modificá-los sem sucesso.

Informações iniciais:

a:b:c:d:e:f

Formato desejado:

a:b

As informações serão coladas em 1 arquivo de texto paste_here.txt e a saída deverá ir para um novo arquivo check.txt .

Minha tentativa atual é:

@echo off
setlocal

for /f "tokens=1,2 delims=:" %%a in (paste_here.txt) do (echo %%a >> check.txt)
    
por DMS 13.10.2014 / 00:03

1 resposta

1

Sua pergunta não está clara. Fornecer entrada e saída de amostra é uma coisa boa, mas você também deve explicar suas necessidades.

Suponho que você tenha colunas delimitadas por vários pontos em cada linha e queira preservar as duas primeiras colunas de cada linha. Também estou assumindo que as larguras das colunas são variáveis, mesmo que seu exemplo tenha apenas uma vez caractere por coluna.

Seu código só preserva a primeira coluna. Não é difícil preservar o segundo:

@echo off
setlocal
for /f "tokens=1,2 delims=:" %%A in (paste_here.txt) do >>check.txt echo %%A:%%B

Mas há um possível problema - ele falhará se a segunda coluna estiver faltando. Por exemplo,

a::c:d:e:f

produzirá

a:c

porque os delimitadores consecutivos são tratados por FOR / F como um único delimitador.

Não é difícil de corrigir, mas requer algumas técnicas de lote avançadas.

  • Você pode preservar toda a linha em um loop externo e usar search / replace para delimitar cada coluna entre aspas. Em seguida, um segundo loop pode ser usado para analisar as colunas e o modificador ~ para remover as cotas durante a saída.

  • A expansão atrasada é necessária para trabalhar com variáveis que são definidas e expandidas dentro do mesmo loop.

  • A expansão atrasada é ativada e desativada para proteger ! que pode aparecer no conteúdo. FOR variável content with ! será corrompida se for expandida enquanto a expansão atrasada estiver ativada.

  • A sintaxe da opção ímpar na instrução FOR / F externa é uma maneira de desabilitar a opção EOL e definir DELIMS para nada, para que ela preserve a linha inteira, independentemente do conteúdo.

Observe também que é mais eficiente (mais rápido) usar parênteses e redirecionar uma vez para o arquivo inteiro, em vez de uma vez por linha.

@echo off
setlocal disableDelayedExpansion
>check.txt (
  for /f delims^=^ eol^= %%A in (paste_here.txt) do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    set "ln="!ln::=":"!""
    for /f "tokens=1,2 delims=:" %%B in ("!ln!") do echo %%~B:%%~C
    endlocal
  )
)

Ou você pode usar um utilitário JScript / batch híbrido chamado REPL.BAT para realizar sua tarefa de maneira muito eficiente em uma única etapa . REPL.BAT executa uma pesquisa / substituição de regex em stdin e grava o resultado em stdout. É um script puro que será executado em qualquer máquina Windows do XP em diante.

type paste_here.txt | repl "^(.*?:.*?):.*" $1 >check.txt
    
por 13.10.2014 / 06:24