У меня есть куча файлов CSV для ежедневной обработки. Они имеют постоянную форму с 19 COMMAS, чтобы появиться в каждом файле. В файле есть смесь строк, временных отметок, целых чисел и чисел с плавающей запятой. Файл всегда заканчивается набором CR-LF.

Каждый файл имеет только одну строку этого текста, которая предоставляет набор информации, которая затем обрабатывается позже.

Проблема возникает из-за того, что время от времени (раз в 1000 файлов) устройство, которое отвечает за создание этого файла, создает НЕПРАВИЛЬНЫЙ файл. Некоторая информация отсутствует.

Мне нужно отделить эти файлы от всех хороших файлов, прежде чем обрабатывать их дальше.

Потратив некоторое значительное количество времени, пытаясь найти наиболее надежный способ решения этой проблемы, я пришел к выводу, что, поскольку файл неполон, в нем отсутствуют некоторые COMMAS.

Поэтому я хочу посчитать количество COMMAS, появляющееся в файле CSV. Правильный файл должен иметь 19 запятых, любые проблемные файлы, которые я обнаружил за последние полгода, имели бы МЕНЬШЕ, чем это. У них также есть CR-LF, отсутствующий в конце линии. Они просто заканчиваются запятой после некоторого значения, и это все.

Пример хорошего файла 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

Пример неверного файла CSV:

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

Мой вопрос: как я могу посчитать количество COMMAS в одном файле CSV, и если это количество не соответствует определенному числу для выполнения определенной операции (например, переместить этот неверный файл в папку ERRORS, с которой я мог бы иметь дело позже). Если файл имеет правильное количество COMMAS, просто позвольте ему быть. Иными словами, мне нужно переместить неправильно отформатированные CSV-файлы в папку ERRORS и оставить правильно отформатированные CSV-файлы такими, какими они были.

К вашему сведению: файлы CSV всегда содержат только одну строку данных.

Я экспериментировал с определенными решениями, которые пытаются найти и посчитать экземпляры определенных строк в файле TXT, но это ни к чему не приводит. Возможно, потому что моя строка - просто знак COMMA ... Я не знаю.

Я был бы очень признателен вам за помощь в этом вопросе.

4 ответа4

2

Регулярное выражение FINDSTR $ только позиции перед CR. Поэтому, если в ваших недопустимых файлах отсутствует CR-LF, вы можете использовать следующий вкладыш, чтобы переместить все проблемные CSV-файлы в папку ошибок.

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

Вы должны удвоить проценты, если поместите команду в пакетный скрипт.

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

Если вы предпочитаете, вы можете использовать более сложное регулярное выражение для поиска строк, которые не содержат 19 запятых:

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

Но простой подсчет запятых может быть ненадежным, потому что указанные значения могут также содержать запятые, как указывает LotPings в своем ответе.

1

Как подсчитать , в CSV файл?

Используйте следующий пакетный файл (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

Заметки:

  • Замените здесь rem handle error here на ваш код обработки ошибок

Пример использования:

> 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

Дальнейшее чтение

  • Индекс AZ командной строки Windows CMD - Отличный справочник по всем вопросам, связанным с командной строкой Windows.
  • dir - Показать список файлов и подпапок.
  • for /f - Циклическая команда против результатов другой команды.
  • if - Условно выполнить команду.
  • set - отображать, устанавливать или удалять переменные окружения CMD. Изменения, сделанные с помощью SET, будут сохраняться только в течение текущего сеанса CMD.
  • переменные - извлечение части переменной (подстроки).
1

Вопрос должен быть: Как я могу убедиться, что файл CSV имеет 20 столбцов / полей

Предполагая, что строки в файле не заключены в кавычки и не содержат запятых, этот пакет будет делать:

@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

Партия заключает строку в двойных кавычках , а также заменяет каждую одиночную , с "," так что каждый столбец в кавычках. Все это передается в подпрограмму :Count считать, где аргументы подсчитываются и сдвигаются до тех пор, пока не исчезнут. Если количество отличается от 20, эхо выдает сообщение об ошибке. Это может быть заменено командой перемещения.

0

Простой способ пакетного подсчета строковых символов в файле

Вы можете использовать пакетный сценарий и поставить простую логику в нем , чтобы создать динамический сценарий PowerShell , чтобы сделать , запятые символов, установите счетчик переменной, и использовать эту переменную в соответствии с остальной частью операций процесса в логика пакетного скрипта.

Скрипт PS не нужно создавать динамически, и вы могли бы использовать статический скрипт PS. Вы можете передать полный путь PS Script в качестве первого аргумента в ваш пакетный скрипт, чтобы использовать его соответственно.

Это легко ... сделано ... дальше !!

Пример пакетного скрипта

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

Вы бы поместили простое условие IF в свой пакетный скрипт и использовали команду перемещения для перемещения файла, если он совпадает или не совпадает с числом, так как у вас есть эта логика в существующем пакетном скрипте.


Дополнительные ресурсы

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .