Как изменить текст внутри CSV-файла из командной строки - PullRequest
0 голосов
/ 22 мая 2019

У меня есть набор данных из моей информационной системы для студентов, и я хочу изменить имя пользователя в с test.student на адрес электронной почты test_student@testdomain.com, который находится в столбце D .csv файл.

По существу это добавит @testdomain.com к тому, что в настоящее время в столбце D.

Вот пример данных:

Studentnumber,lastname,firstname,useraccount,gradyear,coursenumber,gradesem1,gradesem2,gradefinal
17553,test,student,test_student,2016,1811,A,_,_

Я взял это из семпла, чтобы поиграть, и, похоже, он не изменяет col4, как я пытался его получить.

@echo off
setlocal enabledelayedexpansion
set inputCSV=C:\Users\Administrator\Desktop\studentgrades.csv
set outputCSV=C:\Users\Administrator\Desktop\outputtest.csv

(for /f "tokens=1-9* delims=," %%a IN (%inputCSV%) DO (
  set "col4=%%d"
  set "col4=!col4:foo=bar!"
  set "col4=!col4:test=abc!"
  echo %%a,%%b,%%c,!col4!,%%e,%%f,%%g,%%h,%%i
))>%outputCSV%

Ожидаемый результат изменится с:

17553,test,student,test_student,2016,1811,A,_,_

на это:

17553,test,student,test_student@testdomain.com,2016,1811,A,_,_

1 Ответ

0 голосов
/ 22 мая 2019

Первая ошибка - выбор cmd.exe в качестве интерпретатора сценария для модификации текстового файла.Командный процессор Windows предназначен для выполнения команд и приложений, но не для изменения текстовых файлов.Все остальные интерпретаторы сценариев, установленные в Windows по умолчанию, такие как Windows Script Host с cscript.exe (версия консоли) и wscript.exe (версия Windows GUI) для VBScript и JScript *Сценарии 1009 * или powershell.exe для сценариев PowerShell имеют встроенные функции для изменения текста в файлах.

Однако по неизвестной причине задачу следует выполнять с помощью пакетного файла, интерпретируемого какcmd.exe и так вот решение для пакетного файла.Эту задачу можно выполнить с помощью JREPL.BAT , написанного Дейвом Бенхамом , который является гибридом пакетного файла / JScript, для выполнения замены регулярного выражения в файле с использованием JScript .Так что на самом деле это не просто решение для командного процессора Windows, поскольку JScript и cscript.exe используется для реальной работы.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "InputCSV=%UserProfile%\Desktop\studentgrades.csv"
set "OutputCSV=%UserProfile%\Desktop\outputtest.csv"

if not exist "%~dp0jrepl.bat" (
    echo Error: Missing file jrepl.bat in "%~dp0".
    goto EndBatch
)
if not exist "%InputCSV%" (
    echo Error: Missing input file "%InputCSV%".
    goto EndBatch
)

call "%~dp0jrepl.bat" "^((?:[^,]*,){3}[^,]*)" "$1@testdomain.com" /F "%InputCSV%" /O "%OutputCSV%"

:EndBatch
endlocal
pause

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

Затем пакетfile проверяет, существует ли вообще входной файл, и выдает сообщение об ошибке, если это не так.

Last JREPL.BAT вызывается с поиском по регулярному выражению и заменяет строку для заменыс записью измененного содержимого в указанный выходной файл.

Значение выражения поиска:

  • ^ ... начинать каждый поиск с начала строки.
  • ( ... ) ... - группа захвата.Все, что найдено с помощью выражения внутри цикла, имеет обратную ссылку с $1 в строке замены, чтобы сохранить его неизменным.
  • (?: ... ) ... - это группа без захвата, используемая здесь для применениявыражение несколько раз.
  • [^,] ... - это определение класса отрицательных символов, чтобы найти любой символ NOT , являющийся запятой.
  • * ...является множителем, применяемым к определению класса отрицательных символов, чтобы найти 0 или более символов, не являющихся запятой.
  • , ... буквальная запятая должна быть найдена после 0 или болеесимволы, не являющиеся запятыми.
  • {3} ... выражение для немаркированной группы должно применяться ровно три раза для положительного совпадения.
  • [^,]* .. еще раз любоесимвол, кроме запятой 0 или более раз должен быть найден для положительного совпадения.

Таким образом, этот поиск и замена вставляет слева в четвертую запятую строку @testdomain.com и ничего не меняетеще в файле CSV.

ThiПростое решение поиска и замены работает только при следующих условиях:

  1. Четвертое значение данных не заключено в ", так как в противном случае @testdomain.com будет неправильно введен между " в конце строкового значенияи запятая интерпретируется как разделитель между значениями поля.
  2. Ни одно из первых четырех значений поля не содержит запятую в качестве литерального символа в строке значений в двойных кавычках, иначе @testdomain.com будет вставлено в неправильную позицию в данныхстрока.
  3. Ни одно из первых четырех значений поля не содержит один или несколько символов новой строки в строке двойных кавычек, поскольку файл CSV интерпретируется поиском и заменяется строка за строкой, а не строка данных строкой данных.

Все три условия определенно возможны в CSV-файле в соответствии с RFC 4180 , лучше объясненным в статье в Википедии о значениях через запятую .Реальное решение для сценариев или программирования с полной поддержкой CSV было бы необходимо в случае, если одно из этих трех условий не может быть соблюдено содержимым файла CSV.

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

  • call /?... объясняет также %~dp0 ... диск и путь аргумента 0, являющийся самим пакетным файлом.
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?
  • jrepl.bat /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...