批处理:在csv文件中搜索变量和返回行值

时间:2013-12-28 00:16:11

标签: batch-file csv

我有一个包含用户信息的CSV文件。我正在尝试创建一个简单的批处理,允许任何人输入名称或名称或公司的一部分,如果找到结果,则很好地显示它。 csv文件有四列:名称,公司,城市,州 name列有一个逗号,但已用双引号括起来。

[myfile.csv]

Name,Company,City,State
"Smith, John",ACME,Buffalo,NY
"Doe, Jane",Disney,Orlando,FL

[/ myfile.csv]

[searchcsv.bat]

@echo off
cls
setlocal enabledelayedexpansion
set CSVFILE=myfile.csv

:HOME
cls
set column=""
echo ---- USER SEARCH TOOL ----
echo ---- By: Dimitri ----
echo.
echo     1  Search By Name
echo     2  Search By Company
echo     X  Close
echo.

Choice /C 12X /N /M "Please make a selection: "
echo.

IF ERRORLEVEL 3 GOTO :EXIT
IF ERRORLEVEL 2 GOTO :SCHCOMP
IF ERRORLEVEL 1 GOTO :SCHNAME

:SCHNAME
set column=lname
echo ---- Enter Last Name ----
set /p strsearch=
cls
GOTO :FINDIT

:SCHCOMP
set column=Company
echo ---- Enter Company -----
set /p strsearch=
cls
GOTO :FINDIT

:FINDIT
for /f "skip=1 tokens=*" %%A in (%CSVFILE%) do (
set inline=%%A
for /f "tokens=1-5 delims=," %%1 in ("!inline!") do (
set lname=%%1&set fname=%%2&set comp=%%3&set cit=%%4&set stat=%%5
if %column% equ %strsearch% ( GOTO :SHOWRES ) ELSE ( GOTO :NFOUND )
)
)

:SHOWRES
echo Company: %comp%
echo Name: %lname%,%fname%
echo City: %cit%
echo State: %stat%
pause
GOTO :Home

:NFOUND
echo NOT FOUND Try AGAIN
pause
GOTO :HOME

[/ searchcsv.bat]

我希望我可以按姓氏,名字搜索,但由于名字中的逗号,往往会搞砸。

无论如何,希望有人可以指出我做错了什么。感谢您的帮助。

-Dimitri

2 个答案:

答案 0 :(得分:2)

@ECHO OFF
cls
setlocal enabledelayedexpansion
set CSVFILE=myfile.csv

:HOME
cls
set column=""
echo ---- USER SEARCH TOOL ----
echo ---- By: Dimitri ----
echo.
echo     1  Search By Name
echo     2  Search By Company
echo     X  Close
echo.

Choice /C 12X /N /M "Please make a selection: "
echo.

IF ERRORLEVEL 3 GOTO :EOF
IF ERRORLEVEL 2 GOTO  SCHCOMP
IF ERRORLEVEL 1 GOTO  SCHNAME

:SCHNAME
set column=lname
echo ---- Enter Last Name ----
set /p strsearch=
GOTO FINDIT

:SCHCOMP
set column=Company
echo ---- Enter Company -----
set /p strsearch=
GOTO FINDIT

:FINDIT
CLS
SET found=N
for /f "skip=1 tokens=*" %%A in (%CSVFILE%) do (
set inline=%%A
for /f "tokens=1-5 delims=," %%a in ("!inline!") do (
set lname=%%~a&set fname=%%~b&set comp=%%~c&set cit=%%~d&set stat=%%~e
CALL SET fname=!fname:"=!
if %column% equ Company CALL :MATCH "%%~c"
if %column% equ lname CALL :MATCH "%%~a"
)
)
IF %found%==N echo NOT FOUND Try AGAIN
pause
GOTO :Home

:MATCH
SET matchto=%~1
CALL SET matchto=%%matchto:%strsearch%=%%
IF "%matchto%"==%1 GOTO :EOF 
SET found=Y

:SHOWRES
echo Company: %comp%
echo Name: %lname%,%fname%
echo City: %cit%
echo State: %stat%
GOTO :eof

这是一个修订过的例程。我不会说这是防弹......

第一个问题是你不能使用数字作为你的元变量(%%x中的for ...%%x) - 它必须是字母的,并且区分大小写。 (好吧 - 一些符号也可以工作) - 所以 - 上面的%%a%%A是不同的。

下一步:您的数据在针对进行标记时,可能会产生不平衡的引号,例如"SmithJane"。这些可能导致批次错误。通常情况下,解决方法是将变量赋值给%%~x,其中删除封闭的引号 - 但只有当第一个字符为时它才会这样做,因此要求“手动”剥离lname上的引号。

下一篇:数据问题。你可能希望完全匹配,但是输入Cholmondley-Snodgrass是一件痛苦的事。特别是如果你坚持一个案例匹配。此外,您的数据中可能有多少Smith个?就此而言,有时不止一个人为公司工作。

因此,在搜索开始时设置标志found并在找到匹配时将其设置为其他值将允许您选择是否显示失败消息。在修订的例程中CALL MATCH,将公司名称或姓氏作为第一个参数传递意味着您只需将strsearch与传递的值匹配即可。它在引号中传递,以满足包含空格的di Maggio之类的名称。

匹配例程尝试将strsearch中的matchto替换为 = 之后的字符串 - 这是空的。如果是matchto,则会更改found找到匹配的子字符串。因此,如果它保持不变,则不匹配,否则设置goto :label标志并显示记录数据。

我个人厌恶goto :EOF语法。当然,它有效。唯一需要的是. The problem is that there **IS** a difference - not with,其预定义为'此批处理文件的结尾but with转到.来电and来电:标签{{1}}来电标签是两件不同的事情。第一个将例程 INTERNAL 调用到此批处理文件,而第二个调用具有名称的单独批处理文件。如果只在需要时使用,会容易得多。也可以更快地打字。

答案 1 :(得分:0)

您的代码有几个小错误:

  • :SCHCOMP set column=Company comp下方,但存储公司的变量仅命名为set column=comp,因此上一行必须更改为lname
  • 在分配5个值时,您必须注意分配给fnamedelims=,变量的值包含引号,因为%%~1。您必须使用%%~2if %column% equ %strsearch% ( GOTO :SHOWRES ) ELSE ( GOTO :NFOUND )删除引号。
  • 在搜索值的比较中:if %column% equ %strsearch% ...,如果第一个值不是搜索值,则代码会立即转到NFOUND,其余值不会被比较。您需要消除ELSE部分并重新排列代码。
  • 在同一比较中:if /I "!%column%!" equ "%strsearch%" ..."列"变量包含搜索变量的名称(" lname"或" comp"),但您不想比较此名称,而是这样的变量,因此需要额外的延迟扩展:@echo off cls setlocal enabledelayedexpansion set CSVFILE=myfile.csv :HOME cls set column="" echo ---- USER SEARCH TOOL ---- echo ---- By: Dimitri ---- echo. echo 1 Search By Name echo 2 Search By Company echo X Close echo. Choice /C 12X /N /M "Please make a selection: " echo. IF ERRORLEVEL 3 GOTO :EXIT IF ERRORLEVEL 2 GOTO :SCHCOMP IF ERRORLEVEL 1 GOTO :SCHNAME :SCHNAME set column=lname echo ---- Enter Last Name ---- set /p strsearch= cls GOTO :FINDIT :SCHCOMP set column=comp echo ---- Enter Company ----- set /p strsearch= cls GOTO :FINDIT :FINDIT for /f "skip=1 tokens=*" %%A in (%CSVFILE%) do ( set inline=%%A for /f "tokens=1-5 delims=," %%1 in ("!inline!") do ( set "lname=%%~1" & set "fname=%%~2" & set "comp=%%3" & set "cit=%%4" & set "stat=%%5" if /I "!%column%!" equ "%strsearch%" GOTO :SHOWRES ) ) :NFOUND echo NOT FOUND Try AGAIN pause GOTO :HOME :SHOWRES echo Company: %comp% echo Name: %lname%,%fname% echo City: %cit% echo State: %stat% pause GOTO :Home :EXIT 。此外,将比较值括在引号中并使用/ I开关也很方便。

虽然这不是错误,但我建议您不要在FOR命令可替换参数中使用数字。您应始终使用字母并保留批处理文件可替换参数的数字。

{{1}}