使用批处理脚本只读分隔文件中的特定列



我每次都尝试读取具有不同文件结构的csv文件。我想创建一个批处理脚本,仅根据列名称(而不是列位置,因为它每次都会更改)获取特定列,并仅使用这些特定列创建一个新的分隔文件。 例如,我们有以下csv文件数据:

Subject,ID,Error
S1,a_11,error1
S2,b_11,error2

ID 列可以出现在文件中的任何位置,但错误始终是最后一列。 欢迎任何建议。此外,我对批处理脚本知之甚少。非常感谢您的帮助。 提前感谢!

你的问题很不完整。缺少几个细节,所以我必须猜测它们才能编写一个有效的批处理文件:

@echo off
setlocal EnableDelayedExpansion
if "%~1" equ "" echo Usage: %0 column names ... & goto :EOF
rem Read the header and extract column names
set /P "header=" < test.csv
set "n=0"
for %%a in (%header%) do (
set /A "n+=1, column[%%~a]=n"
)
rem Assemble output line from column names given in parameters
set "output="
:nextCol
if not defined column[%~1] echo Not such column: "%~1" & goto :EOF
set "output=!output!,%%!column[%~1]!"
shift
if "%~1" neq "" goto nextCol
rem Generate output
for /F "tokens=1-%n% delims=," %%1 in (test.csv) do echo %output:~1%

这些是缺少的详细信息:

  • 输出文件中的"特定列"在批处理文件参数中给出。
  • 输入文件可以有多少列?超过9个?超过26个?当前代码最多只能输出输入文件中的第 9 列。
  • 数据是否可以包含用引号括起来的逗号(如"Bill,Smith","ID32","Error1")或空列(如S1,,error1)?当前代码无法处理这些情况。

这些点可以在后验版本中更改...

输出示例(假设批处理文件称为 ExtractColumns.bat):

C:UsersAntonioTests> ExtractColumns.bat Id,Subject
ID,Subject
a_11,S1
b_11,S2

无论如何,您的"问题"只是一个代码请求,因此,如果您想获得进一步的支持,您应该表现出您的努力,并在发布的代码上发布有关特定疑问的问题......

我假设你使用Windows NT命令解释器(cmd.exe),因为在DOS/Win9x shell中不可能做到这一点。

以下是您可以在cmd中开始配对CSV的基本代码.exe:

FOR /F "eol=; tokens=1-3 delims=," %%A IN (yourfile.csv) DO (
ECHO Subject: %%A
ECHO ID: %%B
ECHO Error: %%C
)

您应该尝试FOR /?命令并阅读其帮助。它会告诉您如何使用FOR /F命令来解析文件。

使用batchfile并不是 csv 文件的最佳选择。虽然它可以工作,但如果您有以下 csv 字符串,则某些事情(例如使用delims=,)将变得有问题:

"Name,Surname","ID","Error" 
"Bill,Smith","ID32","Error1"

所以上面只有 3 个变量,但包含额外的逗号。

而是使用Powershell

$csvFilename = "D:SomeFile.csv" 
$csv = Import-Csv $csvFilename -Header @("Subject","ID","Error")
foreach ($line in $csv) {
Write-Host "Subject=$($line.Subject)  ID=$($line.ID) Error=$($line.Error)"
}

您可以将其另存为.ps1文件并在Powershell中运行它,或者从命令行调用Powershell。

Windows批处理脚本根本不适合此任务。
虽然在逗号上拆分行非常简单,但仅使用 cmd 提供的内容处理字段中的引号和逗号是不可行的。

为此,请考虑使用Perl或Python等脚本语言。
例如,python 有 csvkit 包,它有一个方便的csvcut可以完全按照你想要的方式做:

csvcut -c column_a,column_c data.csv > new.csv