【问题标题】:Batch: search csv file for variable and return row values批处理:在 csv 文件中搜索变量并返回行值
【发布时间】:2013-12-28 14:48:22
【问题描述】:

我有一个包含用户信息的 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]

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

无论如何,希望有人能指出我做错了什么。感谢大家的帮助。

-迪米特里

【问题讨论】:

  • 这绝对必须成批(即:作业)吗?还是可以使用 vbscript/powershell 脚本?
  • 可以使用vbscript。我现在对 vb 脚本不太熟悉。 Powershell 在我们的环境中被阻止,所以它被淘汰了。

标签: batch-file csv


【解决方案1】:
@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

这是一个修改后的例程。我不会说它是防弹的......

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

接下来:当您的数据针对 进行标记时, 可能会产生不平衡的引号,例如 "SmithJane"。这些可能会导致批量连接。通常,解决方法是将变量分配给%%~x,其中 ~ 删除封闭引号 - 但它仅在第一个字符是 " 时才这样做,因此要求“手动”去掉lname上的引号。

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

因此,在搜索开始时设置标志 found 并在找到命中时将其设置为另一个值,这样您就可以选择是否显示失败消息。 CALLing MATCH 在修改后的例程中,将公司名称或姓氏作为第一个参数传递意味着您可以简单地将 strsearch 与传递的值匹配。它在引号中传递以适应 di Maggio 这样包含空格的名称。

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

我个人厌恶goto :label 语法。当然,它有效。唯一需要的是goto :EOF,它预定义为“此批处理文件结束. The problem is that there **IS** a difference - not withgotobut withcall.call:labelandcall label”是两个不同的东西。第一个调用一个例程 INTERNAL 到这个批处理文件,而第二个调用一个单独的批处理文件。如果只在需要时使用 : 会容易得多。打字也更快。

【讨论】:

  • 工作得很好.. 必须摆脱 ECHO IF "%matchto%"==%1 GOTO :EOF 最后一件事,假设有 3 家公司,ACME-A,ACME-B ,ACME-C,所有三个公司都有不同的用户,我进行了公司搜索,只搜索“ACME”,有没有办法添加类似 if %comp% >1 echo more then one company... then list找到的公司,您是否从列表中选择了一个?感谢您的帮助..
【解决方案2】:

您的代码有几个小错误:

  • :SCHCOMP下面你set column=Company,但是存储公司的变量只命名为comp,所以上一行必须改成set column=comp
  • 在分配 5 个值时,必须注意分配给 lnamefname 变量的值包括引号,因为 delims=,。您必须消除带有%%~1%%~2 的引号。
  • 在搜索值的比较中:if %column% equ %strsearch% ( GOTO :SHOWRES ) ELSE ( GOTO :NFOUND ),如果 第一个值 不是搜索值,您的代码将立即转到 NFOUND 并且不比较其余值。您需要删除 ELSE 部分并重新排列代码。
  • 在同一个比较中:if %column% equ %strsearch% ...“column”变量包含搜索变量的名称(“lname”或“comp”),但您不想比较这样的名称,而是此类变量的 ,因此需要额外的延迟扩展:if /I "!%column%!" equ "%strsearch%" ...。此外,将比较值括在引号中并使用 /I 开关也很方便。

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

@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

【讨论】:

    猜你喜欢
    • 2016-02-23
    • 2010-11-29
    • 2020-02-19
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多