BATCH Script: come posso contare le occorrenze di COMMA in un file CSV o TXT?


0

Ho un sacco di file CSV da elaborare ogni giorno. Hanno una forma costante con 19 virgole per apparire in ogni file. Nel file è presente una combinazione di stringhe, timestamp, numeri interi e cifre float. Il file termina sempre con CR-LF impostato.

Ogni file ha solo 1 riga di quel testo, che fornisce una serie di informazioni che vengono successivamente elaborate.

Il problema sembra che di tanto in tanto (una volta ogni 1000 file) il dispositivo responsabile della generazione di quel file crea il file INCOMPLETE. Mancano alcune informazioni.

Devo separare quei file da tutti i file validi prima di elaborarli ulteriormente.

Dopo aver trascorso un considerevole periodo di tempo a cercare di capire il modo più efficace per risolvere, sono giunto alla conclusione che, poiché il file è incompleto, mancano alcune virgole.

Quindi voglio contare la quantità di COMMAS che appaiono nel file CSV. Il file corretto dovrebbe avere 19 virgole, qualsiasi file problematico che ho scoperto nell'ultimo semestre sarebbe MENO di quello. Hanno anche CR-LF mancante alla fine della linea. Finiscono semplicemente con la virgola dopo un certo valore e basta.

Esempio di un buon file CSV:

STRING1,STRING2,2017-01-20 17:34:08,53.808536,-7.789231,19.5,3,0,STRING3,2017-01-20 17:34:19,2,0,7.9,2,0,1,0,0,0,0

Esempio di file CSV errato:

STRING1,STRING3,2017-01-12 10:11:09,53.779093,-7.494274,

La mia domanda è: come posso contare la quantità di COMMAS in un singolo file CSV e se questa quantità non corrisponde al numero definito per eseguire una determinata operazione (come spostare questo file errato nella cartella ERRORS, che potrei trattare in seguito). Se il file ha la quantità corretta di COMMAS, lascia che sia. Quindi, ho bisogno di un'altra parola per spostare i file CSV formattati in modo errato in una cartella ERRORI e lasciare i file CSV formattati correttamente come erano.

Cordiali saluti: i file CSV contengono sempre solo 1 riga di dati.

Ho sperimentato alcune soluzioni, che stanno cercando di trovare e contare le istanze di determinate stringhe in un file TXT, ma non mi sta portando da nessuna parte. Forse perché la mia stringa è solo un segno COMMA ... Non lo so.

Apprezzerei molto il tuo aiuto in merito.


Cosa hai effettivamente provato e dove ti sei bloccato la sceneggiatura? Deve essere uno script batch? Cosa sta elaborando quei file? Non sarebbe possibile includere il controllo degli errori in quel componente?
Seth

Ho provato questo metodo per trovare le virgole, ma mi dà risultati ZERO :(
Piotruncio


Esiste solo uno script BATCH che prepara i file. Ma se appare questo problema sopra descritto, tutto fallisce. Il processo deve essere eseguito ogni 2 minuti, 24 ore su 24, 7 giorni su 7 e dovrà elaborare centinaia di file per esecuzione.
Piotruncio

Viene visualizzato un errore durante l'esecuzione di quello script?
Seth

Risposte:


1

Come contare le occorrenze di ,in un file CSV?

Utilizzare il seguente file batch (CountCommas.cmd):

@echo off
setlocal EnableDelayedExpansion
set _comma=,
for /f "usebackq" %%a in (`dir /b /s *.csv`)  do (
  set _file=%%a
  set count=0
  for /f "usebackq tokens=*" %%b in (`type !_file!`) do (
    set _line=%%b
    call :count
  )
)
goto :done
:count
    if !_line:~0^,1! equ !_comma! (
      set /a count+=1
      )
    if "!_line:~1!" neq "" (
      set _line=!_line:~1!
      goto :count
      )
    echo file !_file! contains !count! commas
    if !count! neq 19 (
      echo error
      rem handle error here
      )
    )
:done
endlocal

Gli appunti:

  • Sostituisci rem handle error herecon il tuo codice di gestione degli errori

Esempio di utilizzo:

> type bad.csv
STRING1,STRING3,2017-01-12 10:11:09,53.779093,-7.494274,
> type good.csv
STRING1,STRING2,2017-01-20 17:34:08,53.808536,-7.789231,19.5,3,0,STRING3,2017-01-20 17:34:19,2,0,7.9,2,0,1,0,0,0,0
> CountCommas
file F:\test\bad.csv contains 5 commas
error
file F:\test\good.csv contains 19 commas

Ulteriori letture

  • Un indice AZ della riga di comando CMD di Windows - Un riferimento eccellente per tutte le cose relative alla riga cmd di Windows.
  • dir - Visualizza un elenco di file e sottocartelle.
  • for / f - Comando loop contro i risultati di un altro comando.
  • if : esegue in modo condizionale un comando.
  • set - Visualizza, imposta o rimuove le variabili di ambiente CMD. Le modifiche apportate con SET rimarranno solo per la durata della sessione CMD corrente.
  • variabili : estrae parte di una variabile (sottostringa).

+1 per non aver mescolato roba di PowerShell lì dentro
Master Azazel,

Ciao David, grazie per quello. Ho usato la tua sceneggiatura e funziona FINE. Ho modificato la Directory per indirizzare lo script nella posizione di tutti i file CSV e ho modificato la parte ERROR HANDLING per SPOSTARE i file "problematici" in una posizione separata. Ma quello che ho notato, è che se ci sono 500 file CSV in quella cartella, ci vuole molto tempo per l'elaborazione. È perché deve essere eseguito in un ciclo 500 volte?
Piotruncio

David, quando ho provato a inserire quel codice di conteggio delle virgole in un altro file BAT che fa l'intero lavoro di elaborazione di quei file CSV (le virgole di conteggio sono solo una parte di verifica per vedere se i file in una cartella di dare hanno una struttura adeguata) solo una volta. Non ha controllato tutti i file. Lo so, perché funziona molto velocemente e ha trovato solo 1 file errato nella cartella (che è stato il primo file da controllare) e quindi ha eseguito il resto dello script BATCH. Quando eseguo il tuo script da un file separato, controlla tutti i file CSV e trova entrambi i file difettosi.
Piotruncio

Sì. Il ciclo esterno viene eseguito una volta per ogni file e il ciclo interno viene eseguito una volta per ogni carattere per contare le virgole.
DavidPostill

Prova calling CountCommasinvece di includere il codice in un altro file batch.
DavidPostill

2

L' $espressione regolare FINDSTR corrisponde solo alla posizione prima di un CR. Quindi, se i file non validi mancano di CR-LF, è possibile utilizzare il seguente liner per spostare tutti i file CSV problematici nella cartella degli errori.

for /f "eol=: delims=" %F in ('findstr /vm $ *.csv') do @move /y "%F" error >nul

È necessario raddoppiare le percentuali se si inserisce il comando in uno script batch.

@echo off
for /f "eol=: delims=" %%F in ('findstr /vm $ *.csv') do move /y "%%F" error >nul

Se preferisci, puoi usare un'espressione regolare più complicata per cercare le righe che non contengono 19 virgole:

@echo off
for /f "eol=: delims=" %%F in (
  'findstr /vm ".*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*," *.csv'
) do move /y "%%F" error >null

Ma il semplice conteggio delle virgole potrebbe non essere affidabile, perché i valori indicati possono contenere anche virgole, come sottolinea LotPings nella sua risposta.


1
Ciao Dave, ho pensato che potresti voler aggiornare la tua risposta dal tuo codice DosTips .
Squashman,

1

La domanda dovrebbe essere Come posso assicurare che il file CSV abbia 20 colonne / campi

Presumendo che le stringhe nel file non siano quotate e non contengano virgole questo batch farà:

@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
CD /d "X:\path\to\csv-folder"
Set Cnt=0
For %%A in (*.csv) Do Set File="%%A"&Set /P CSV=<%%A&Call :Count "!CSV:,=","!"
Goto :Eof
:Count
If "%~1" Neq "" Shift & Set /A Cnt+=1 & Goto :Count
If %Cnt% Neq 20 Echo %File% has %Cnt% Columns
Set "CSV="
Set Cnt=0

Il batch racchiude la riga tra virgolette doppie e sostituisce anche ogni singola virgola ,con ","così ogni colonna viene quotata. Tutto ciò è passato alla subroutine in :Countcui gli argomenti vengono contati e spostati fino a quando non sono più presenti. Se il conteggio è diverso da 20, un'eco emette il messaggio di errore. Questo può essere sostituito da un comando di spostamento.


0

Un modo semplice con batch per contare i caratteri stringa in un file

È possibile utilizzare uno script batch e inserire la logica semplice in esso per creare uno script PowerShell dinamico per eseguire il conteggio dei ,caratteri virgole, impostare il conteggio su una variabile e utilizzare tale variabile di conseguenza con il resto delle operazioni di processo nel batch logica dello script.

Lo script PS non deve essere creato in modo dinamico e potresti passare a utilizzare uno script PS statico. È possibile passare il percorso completo di PS Script come primo argomento allo script batch da utilizzare di conseguenza.

Questo è facile ... fatto ... il prossimo !!

Esempio di script batch

ECHO ON

SET file=C:\folder\file.txt

CALL :CreatePSCommaCount
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0 
CD /D "%PowerShellDir%" 
FOR /F "DELIMS=" %%A IN ('Powershell -ExecutionPolicy Bypass -Command "& '%DynPSCommaCount%'"') DO SET "commacount=%%A"

IF NOT %commacount%==19 GOTO EOF
<other batch script logic below here since count is 19 (or whatever you need it to be)>
GOTO EOF

:CreatePSCommaCount
SET DynPSCommaCount=%Temp%\TempCommaCount.ps1
IF EXIST "%DynPSCommaCount%" DEL /Q /F "%DynPSCommaCount%"
ECHO $file  = GC "%file%"                                               >>"%DynPSCommaCount%"
ECHO $Match = Select-String -InputObject $file -Pattern "," -AllMatches >>"%DynPSCommaCount%"
ECHO $Match.Matches.Count                                               >>"%DynPSCommaCount%"
GOTO EOF

Dovresti inserire una semplice condizione IF nello script batch e utilizzare il comando move per spostare il file se corrisponde o meno a un numero, tuttavia hai quella logica nello script batch esistente.


Ulteriori risorse

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.