Использовать пакетную обработку файлов для удаления последнего символа

У меня есть процесс, где входящий файл CSV и запятые после последней записи.

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

В настоящее время у меня есть этот кусок кода для записи каждой строки в новый файл:

for /f "tokens=* delims=" %%x in (file.csv) do echo %%i >> test.txt

И я пытался использовать что-то вроде echo %string:~0,-1% удалить запятую в сочетании, но мне не повезло. Я не думаю, что %%i можно использовать так же, как на строку, указанную выше. Я пытался записать %%i в строку, но, похоже, у меня тоже неправильный синтаксис.

[редактировать]

Я запускаю файл через скрипт vbs, чтобы заменить запятые на каналы (, = |), поэтому, если есть более простой способ сделать это как часть этого процесса, в моем поиске stackru попытаться решить эту проблему, прежде чем спросить, я нашел эта строка, которая, как я думал, может помочь:

strNewText = strNewText.Substring(0,strNewText.Length-1)

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

rem CREATE Find And Replace Text VBS SCRIPT
echo Const ForReading = 1 > "%tmp%\fart.vbs"
echo Const ForWriting = 2 >> "%tmp%\fart.vbs"
echo strFileName = Wscript.Arguments(0) >> "%tmp%\fart.vbs"
echo strOldText = Wscript.Arguments(1) >> "%tmp%\fart.vbs"
echo strNewText = Wscript.Arguments(2) >> "%tmp%\fart.vbs"
echo Set objFSO = CreateObject("Scripting.FileSystemObject") >> "%tmp%\fart.vbs"
echo Set objFile = objFSO.OpenTextFile(strFileName, ForReading) >> "%tmp%\fart.vbs"
echo strText = objFile.ReadAll >> "%tmp%\fart.vbs"
echo objFile.Close >> "%tmp%\fart.vbs"
echo strNewText = Replace(strText, strOldText, strNewText) >> "%tmp%\fart.vbs"
echo strNewText = strNewText.Substring(0,strNewText.Length-1) >> "%tmp%\fart.vbs"
echo Set objFile = objFSO.OpenTextFile(strFileName, ForWriting) >> "%tmp%\fart.vbs"
echo objFile.WriteLine strNewText >> "%tmp%\fart.vbs"
echo objFile.Close >> "%tmp%\fart.vbs"

(все эхо связано с тем, что я генерирую vbs во время выполнения пакета, я склонен находить вещи проще, когда все сделано в одном файле, этот файл vbs затем удаляется позже в процессе).

3 ответа

@if (@This==@IsBatch) @then
@echo off
rem **** batch zone *********************************************************

    type inputfile.csv | cscript //nologo //e:javascript "%~f0" > outputfile.csv

    exit /b

@end
// **** Javascript zone *****************************************************
    while (!WScript.StdIn.AtEndOfStream) WScript.StdOut.WriteLine(WScript.StdIn.ReadLine().replace(/,[\s,]+$/,''));

Это гибридный пакетный /javascript файл. Сохраните как пакетный файл, выполните, и файл inputfile.csv будет передан в cscript.exe, который будет выполнять код javascript, включенный в тот же пакетный файл, перебирать передаваемые данные и удалять все запятые и последние пробелы от последней запятой до конца линия. Вывод из трубы отправляется в outputfile.csv

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

... .replace(/,$/,''));

Я не уверен, что это сработает, но так как вы хотите, чтобы код применялся только для последней строки, я попытался реализовать код иначе, чем в среднем for loop,

@echo off
setlocal enabledelayedexpansion
set previous=
set current=    
ren file.csv file.tmp

3<file.tmp (
:loop
set previous=!current!
set /p current=<&3
if "!current!" == "!previous!" (
Echo !current:~0,-1! >> file.csv
) Else (
Echo !current! >> file.csv
goto :loop
)
)
type file.csv
Echo. &Echo Only delete if file.csv is not corrupt
del /p file.tmp
Endlocal

И это должно делать то, что вы хотите.

Мона.

Вероятно, самое простое решение для вашей проблемы будет sed для Windows:

C:\>sed "s/,$//" <in.csv >out.csv

Вы также можете написать простой VBScript, который делает то же самое:

Set re = New RegExp
re.Pattern = ",$"

Do Until WScript.StdIn.AtEndOfStream
  WScript.Echo re.Replace(WScript.StdIn.ReadLine, "")
Loop

Использование:

C:\>cscript //NoLogo script.vbs <in.csv >out.csv

PowerShell будет еще лучшим вариантом:

PS C:\> (Get-Content 'in.csv') -replace ',$' | Out-File 'out.csv'

Я бы не рекомендовал использовать пакет для этого.

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