如何在命令提示符下修改csv文件中的文本

时间:2019-05-22 16:15:08

标签: windows csv batch-file

我有来自学生信息系统的一组数据,我想将test.student中的用户名更改为{{1}列中的电子邮件地址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,_,_

1 个答案:

答案 0 :(得分:0)

首先犯的错误是选择cmd.exe作为脚本解释器来修改文本文件。 Windows命令处理器设计用于执行命令和应用程序,但不适用于修改文本文件。默认情况下,Windows上安装的所有其他脚本解释器,例如{strong> VBScript 和 JScript的cscript.exe(控制台版本)和wscript.exe(Windows GUI版本)Windows Script Host 脚本或 PowerShell 脚本的powershell.exe具有内置功能,可修改文件中的文本。

但是,由于某些未知的原因,应该使用用cmd.exe解释的批处理文件来完成任务,因此这里提供了一个批处理文件解决方案。可以使用 Dave Benham 编写的JREPL.BAT来完成此任务,该文件是批处理文件/ JScript混合,可以使用 JScript 在文件上运行正则表达式替换。因此,由于JScript和cscript.exe用于完成真正的工作,因此它并不是纯粹的Windows命令处理器解决方案。

@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 是否确实存在于批处理文件的目录中,如果在打印错误消息之前进行打印,则此条件不成立时退出。

然后批处理文件检查输入文件是否存在,如果不是这种情况,则输出错误消息。

最后一个 JREPL.BAT 通过正则表达式搜索和替换字符串来调用,以通过将修改后的内容写入指定的输出文件来进行替换。

搜索表达式的含义是:

  • ^ ...从一行的开头开始每个搜索。
  • ( ... ) ...是一个捕获组。在循环内用表达式找到的所有内容都在替换字符串中用$1进行了反向引用,以保持其不变。
  • (?: ... ) ...是一个非捕获组,在这里用于多次应用表达式。
  • [^,] ...是一个否定的字符类定义,用于查找是逗号的任何字符。
  • * ...是应用于否定字符类定义的乘法器,用于查找0个或多个不是逗号的字符。
  • , ...接下来必须在 0 个字符或多个非逗号字符之后找到文字逗号。
  • {3} ...对于正匹配,非标记组内的表达式必须精确地应用三遍。
  • [^,]* ..再次必须找到除逗号 0 以外的任何其他字符,才能多次匹配。

因此,此搜索和替换操作将字符串@testdomain.com插入到第四个逗号,并且在CSV文件中没有任何改变。

此简单的搜索和替换解决方案仅在以下情况下有效:

  1. 第四个数据值未包含在"中,否则将在字符串值末尾的@testdomain.com之间插入",并且逗号被解释为字段值之间的分隔符。
  2. 前四个字段值中没有一个在双引号值字符串中包含逗号作为文字字符,否则@testdomain.com会插入到数据行的错误位置。
  3. 前四个字段值中没有一个在双引号值字符串中包含一个或多个换行符,因为CSV文件由搜索解释并逐行替换,而不是逐行替换数据。

根据RFC 4180更好地解释的comma-separated values,这三个条件在CSV文件中绝对是可能的。如果无法通过CSV文件的内容保留这三个条件之一,则需要一个具有完全CSV支持的真实脚本或编程解决方案。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /? ...也解释了%~dp0 ...参数0的驱动器和路径是批处理文件本身。
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?
  • jrepl.bat /?