在批处理文件中为/ f中提取某些令牌

时间:2013-12-13 19:56:12

标签: batch-file

好的,我是新来的,也是批处理脚本的新手,但我开始掌握它了。

这就是我想要做的。我有一个文件,其中包含我从另一个文件中提取的行,并且是分隔符。这条线看起来像这样:

COL1 COL2 COL3 COL4 COL5 COL6
Date name ID   Cost dept site

我要做的是将某些标记拉出来设置一些文本文件。但是我遇到处理空白令牌/列的问题,而且有些列中有空格。这是我的代码,但它没有返回我要找的内容

SET datalocation=mydatalocation
for /f "skip=1 tokens=1,4,6" %%a in (%datalocation%\filename.txt) do (
    echo %%a > %datalocation%\col1.txt
    echo %%b > %datalocation%\col4.txt
    echo %%c > %datalocation%\col6.txt
    )

我得到的输出是一团糟。 COL1.txt将包含col1的一半和col2中的所有col2。 Col4.txt和Col6.txt两个状态echo都关闭了,所以我假设返回的变量是空白的。

任何帮助将不胜感激。

附加样本数据

上次连接设备ID操作系统操作系统级别串行号码MAC地址主要用户ID主要名字主要姓氏主要费用代码已开票UID开票名字开票姓氏开帐单费用代码 12/10/2013 8:16 Mycomputer Microsoft Windows 7企业版6.1.7601 [Build 7601] Service Pack 1 1234abc 4437e6a3e5d5 JasonM Jason Moseley CB0000012345 JasonM Jason Moseley CB0000012345

3 个答案:

答案 0 :(得分:3)

@ECHO OFF
goto final
SETLOCAL
SET "sourcedir=."
SET "tab=   "
FOR /f "skip=1tokens=1,2,4delims=%tab%" %%a IN (%sourcedir%\q20574891.txt
 ) DO (
  ECHO(%%a >>"%sourcedir%\col1.txt"
  ECHO(%%b >>"%sourcedir%\col2.txt"
  ECHO(%%c >>"%sourcedir%\col4.txt"
)
ENDLOCAL
:: Environment is now cleared of changes
SETLOCAL
SET "sourcedir=."
FOR /f "delims=" %%a IN (%sourcedir%\q20574891.txt) DO SET "tab=%%a"&GOTO tabset
:tabset
SET tab=%tab:*Col 1=%
SET tab=%tab:~0,1%
ECHO tab=+%tab%+ >u:\junk.txt
FOR /f "skip=1tokens=1,2,4delims=%tab%" %%a IN (%sourcedir%\q20574891.txt
 ) DO (
  ECHO(%%a >>"%sourcedir%\col1.txt"
  ECHO(%%b >>"%sourcedir%\col2.txt"
  ECHO(%%c >>"%sourcedir%\col4.txt"
)
ENDLOCAL
:: Environment is now cleared of changes
:final
SETLOCAL enabledelayedexpansion
SET "sourcedir=."
FOR /f "delims=" %%a IN (%sourcedir%\q20574891.txt) DO SET "tab=%%a"&GOTO tabset
:tabset
:: Need to change the string between * and = on next line to column 1's name
SET tab=%tab:*Last Connect=%
SET tab=%tab:~0,1%
FOR /f "skip=1delims=" %%w IN (%sourcedir%\q20574891.txt) DO (
 SET "line=%%w"
 SET "line="!line:%tab%="%tab%"!""
 FOR /f "tokens=1-15delims=%tab%" %%a IN ("!line!"
  ) DO (
   IF NOT "%%~a"=="" ECHO(%%~a >>"%sourcedir%\col01.txt"
   IF NOT "%%~b"=="" ECHO(%%~b >>"%sourcedir%\col02.txt"
   IF NOT "%%~c"=="" ECHO(%%~c >>"%sourcedir%\col03.txt"
   IF NOT "%%~d"=="" ECHO(%%~d >>"%sourcedir%\col04.txt"
   IF NOT "%%~e"=="" ECHO(%%~e >>"%sourcedir%\col05.txt"
   IF NOT "%%~f"=="" ECHO(%%~f >>"%sourcedir%\col06.txt"
   IF NOT "%%~g"=="" ECHO(%%~g >>"%sourcedir%\col07.txt"
   IF NOT "%%~h"=="" ECHO(%%~h >>"%sourcedir%\col08.txt"
   IF NOT "%%~i"=="" ECHO(%%~i >>"%sourcedir%\col09.txt"
   IF NOT "%%~j"=="" ECHO(%%~j >>"%sourcedir%\col10.txt"
   IF NOT "%%~k"=="" ECHO(%%~k >>"%sourcedir%\col11.txt"
   IF NOT "%%~l"=="" ECHO(%%~l >>"%sourcedir%\col12.txt"
   IF NOT "%%~m"=="" ECHO(%%~m >>"%sourcedir%\col13.txt"
   IF NOT "%%~n"=="" ECHO(%%~n >>"%sourcedir%\col14.txt"
   IF NOT "%%~o"=="" ECHO(%%~o >>"%sourcedir%\col15.txt"
 )

)     ENDLOCAL

GOTO :EOF

真的需要了解更多关于您的数据的信息。以上是两种方式 - 第一种方式假设您可以在源中插入真实的实时 Tab 。第二个从数据文件中导出tab,但依赖于您知道第1列的标题(在我的测试中Col 1

下一个问题 - 而我未提及的问题是FOR/F将一系列分隔符视为单个分隔符,因此如果数据包含

标签 标签

然后需要额外的处理,而

标签 空间 标签

将是安全的。

确定 - 已编辑以处理标签序列。惊讶于我使用了与dbenham相同的技术 - 即使是相同的临时数据名line

我添加了一项改进,以便col2不会收到空列的空行,并且我的列号因测试目的而不同 - 缺少样本数据:(

啊 - 再次调整。现在大部分的演示解决方案都被忽略了 - 为了任何可能感兴趣的人,我会把它留在那里。

您需要更改指定位置的列名以匹配第1列的名称。任何进程都无法确定列分隔符是什么。在没有测试数据的情况下,我只使用“Col 1”作为测试数据列名。

或者,可能最好,您可以将变量tab设置为真实的标签 - 这里有点难以展示。语法显示在上面代码的第五行 - 引号确保在指定的值中包含尾随空格 NOT

答案 1 :(得分:2)

下面的代码将通过首先将所有值括在引号中来正确处理缺失值(连续制表符分隔符)。

默认的DELIMS选项是制表符和空格,因此如果值可能包含空格,则必须将DELIMS显式设置为制表符。

下面定义选项卡的代码应该在脚本中有一个硬编码的制表符

@echo off
setlocal enableDelayedExpansion

:: Define a TAB character (hard coded tab - not spaces)
set "tab=   "

:: Read entire line without parsing tokens
set "datalocation=mydatalocation"
for /f usebackq^ skip^=1^ delims^=^ eol^= %%L in ("%datalocation%\filename.txt") do set "line=%%L"

:: Put quotes around all token values:  <tab>B<tab>C   becomes   ""<tab>"B"<tab>"C"
set "line="!line:%tab%="%tab%"!""

:: Parse the values. Use `~` to remove enclosing quotes.
:: Enclose ECHO statement in parentheses to prevent unwanted trailing space in output
:: Use ECHO( to prevent ECHO is off message if value is empty
for /f "eol=%tab% delims=%tab% tokens=1,4,6" %%A in ("!line!") do (
  (echo(%%~A) >"%datalocation%\col1.txt"
  (echo(%%~B) >"%datalocation%\col4.txt"
  (echo(%%~C) >"%datalocation%\col6.txt"
)

答案 2 :(得分:0)

这是我最终用于我的代码的结果。

@echo off
setlocal enableDelayedExpansion
SET "sourcedir=."
FOR /F "delims=" %%L in (%sourcedir%\filename.csv) DO (
        set "line=%%L,"

    set "line=#!line:,=,#!"

    FOR /F "tokens=7,8,9,11 delims=," %%a in ("!line!") DO (
        IF NOT "%%~a"=="" ECHO(%%~a >>"%sourcedir%\col01.txt"
        IF NOT "%%~b"=="" ECHO(%%~b >>"%sourcedir%\col02.txt"
        IF NOT "%%~c"=="" ECHO(%%~c >>"%sourcedir%\col03.txt"
        IF NOT "%%~d"=="" ECHO(%%~d >>"%sourcedir%\col04.txt"
        )
)