Пакетный файл / автоматизация для добавления LF и CR (EOL) в конец нескольких файлов.csv

У меня есть куча .csv файлы, которые генерируются извне и периодически отправляются мне. каждый из них содержит одну строку текста с 31 "столбцами". Однако ни у одного из них нет EOL (без LF отдельно или с CR), поэтому, когда я пытаюсь объединить любой из этих файлов, я получаю больше столбцов в одной строке вместо строки для каждого файла.

Я хотел бы, чтобы способ автоматически добавлять это в конец каждого из этих файлов в пакете, с выходными данными, имеющими то же имя файла, что и исходный файл, возможно, с добавлением символа в начале имени, поэтому я новый Процесс был завершен. Ex: originalFile.csv>> 1_originalFile.csv,

Я попытался создать файл с именем "eol.csv"Это было просто (LF и CR), и я создал пакет, который бы добавил это в конец всех моих файлов, но, поскольку я новичок в написании пакетных файлов, я был значительно неудачен.

Если бы это можно было выполнить для каждого файла, когда он был помещен в папку, это было бы еще лучше.

Спасибо за любые мысли по этому поводу!

3 ответа

Решение

Это будет искать все .csv имена файлов для строки _fixed, и на тех, кто не имеет его, вставит пустую строку и переименует ее. Конечно замени pathToWherever с правильным путем для вас, и /s Опция может быть добавлена, чтобы разрешить поиск в подпапках по названному пути тоже.

@echo off
for /r "C:\pathToWherever\" %%G in (*.csv) do (
    echo %%G | findstr /c:"_fixed" || (
        echo:>>%%G
        ren "%%G" "%%~nG_fixed.csv" 
    )
)

Регулярное выражение FINDSTR $ распознает конец строки как позицию непосредственно перед возвратом каретки. Так findstr /v $ будут соответствовать только строки, которые не содержат возврат каретки. Вы можете использовать этот факт для добавления возврата каретки / перевода строки только к тем файлам, которые в ней нуждаются, без необходимости переименовывать какие-либо файлы.

Все, что вам нужно, это следующий вкладыш из командной строки:

for /f "eol=: delims=" %F in ('findstr /m /v $ *.csv') do @(echo()>>"%F"

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

Так как все echoконец в CRLF, и вы можете использовать echo/ чтобы отразить CLRF сам по себе, вы можете просто использовать перенаправление вывода, чтобы добавить CLRF к каждому из файлов CSV.

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

@for %%A in (%*) do echo/ >>%%A

Кстати, эта строка - весь сценарий.

Есть несколько способов добавить разрыв строки к (последней строке) файла, если он еще не присутствует:

  1. findstr:

    findstr /V "$" "data.csv" > nul && echo/>> "data.csv"
    

    Этот обратный (/V) search соответствует последней строке, только если она не заканчивается разрывом строки. В таком случае && позволяет выполнить следующую команду, которая просто добавляет разрыв строки.

    Ограничения:

    • строки должны быть короче 8К символов;
  2. find:

    < "data.csv" find /V "" > "data.csv.tmp" && move /Y "data.csv.tmp" "data.csv" > nul
    

    Этот поиск соответствует всем строкам, findдобавляет перенос строки к каждой возвращаемой строке, даже к последней, когда его нет. Временный файл необходим, поскольку невозможно читать и записывать в один и тот же файл. Если ошибок нет, && позволяет выполнить следующую команду, которая перемещает временный файл в исходный.

    Ограничения:

    • для этого требуется временный файл;
    • строки должны быть короче 4К символов;
  3. more:

    more "data.csv" > "data.csv.tmp" && move /Y "data.csv.tmp" "data.csv" > nul
    

    Это просто возвращает все строки; moreдобавляет перенос строки к каждой возвращаемой строке, даже к последней, когда его нет. Временный файл необходим, поскольку невозможно читать и записывать в один и тот же файл. Если ошибок нет, && позволяет выполнить следующую команду, которая перемещает временный файл в исходный.

    Ограничения:

    • для этого требуется временный файл;
    • файл должен быть короче 64К строк;
    • строки должны быть короче 64К символов;
    • TABs стать расширенным до SPACEs;
  4. sort:

    sort "data.csv" /+65535 /REC 65535 | sort /+65535 /REC 65535 /O "data.csv"
    

    Это просто возвращает все строки; sortдобавляет перенос строки к каждой возвращаемой строке, даже к последней, когда его нет. Удивительно, но временный файл не требуется (я тестировал файл размером ~ 30 МБ без потери данных из-за конфликтов ввода-вывода). Тем не менее, это, вероятно, самый медленный метод здесь из-за трубы (|).

    Ключ состоит в том, чтобы установить позицию символа для сортировки, выходящую за рамки данных. В таких случаях,sortкажется, просто откатывает весь файл; это причина использования двухsortкоманды. Но я очень быстро протестировал это с одним файлом в Windows 7, так что будьте осторожны с этим.

    Ограничения:

    • строки должны быть короче 64К символов;

Все вышеперечисленные подходы легко реализовать в forцикл для применения к нескольким файлам; просто заменитеdata.csv с for затем метапеременная (продемонстрирована здесь в варианте 1.):

for %I in ("*.csv") do @(findstr /V "$" "%~I" > nul && echo/>> "%~I")

Помните, что %-знаки необходимо удвоить при использовании этого кода в пакетном файле.

Другие вопросы по тегам