【问题标题】:Remove header while merging multiple .csv files using batch使用批处理合并多个 .csv 文件时删除标题
【发布时间】:2016-03-31 06:32:21
【问题描述】:

我已经编写了将示例文件连接到单个文件中的代码,减去每个文件的标题。

输入文件:

文件 1:

[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00032116,21238,60304PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14
00032116,21238,81790PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14

文件 2:

[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00024067,15562,9942PRMI,1,2014-09-16,2016-12-31,gintgUser,gintgUser,2016-02-21 05:59:43,2016-02-21 05:59:43

预期输出:

[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00024067,15562,9942PRMI,1,2014-09-16,2016-12-31,gintgUser,gintgUser,2016-02-21 05:59:43,2016-02-21 05:59:43
00032116,21238,60304PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14
00032116,21238,81790PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14

实际输出:

[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00024067,15562,9942PRMI,1,2014-09-16,2016-12-31,gintgUser,gintgUser,2016-02-21 05:59:43,2016-02-21 05:59:43
00032116,21238,60304PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14
[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00032116,21238,81790PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14

请找到以下用于此操作的代码:

@echo off
break>Combined.csv
cls
setlocal enabledelayedexpansion

if exist C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv del C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv

dir /a-d /b C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\ContractEligibility_*.csv>C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\dirfiles.txt

cd C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\

for /f "tokens=*" %%A in (C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\dirfiles.txt) do (
    set /p header=<%%A
    if "!header!" neq "" (
        (echo(!header!)>Combined.csv
        goto :break_for
    )

)
:break_for

for /f "tokens=*" %%A in (C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\dirfiles.txt) do (
        more +1 %%A>>Combined.csv
   )

del dirfiles.txt
}

谁能帮我解决这个问题。我是批处理脚本的新手,无法调试此问题。

【问题讨论】:

  • 请学习如何正确格式化代码部分;使用编辑区域中的{} 按钮...
  • 我改进了相同 CSV 文件的格式 - 请参阅我的 edit;请注意,我从示例文件 2 中删除了一个截断行,因为我认为它是复制粘贴错误,并且该行没有出现在示例输出文件中;如果我做错了什么,请随时再次编辑帖子...

标签: windows batch-file


【解决方案1】:

关于这个问题的几点说明:

  • 此问题与Windows Batch file execution error 完全相同
  • 这个问题有 4 个答案,其中一个是我的。
  • 在我的回答中,我要求您发布一小部分数据文件,但您从未回复。
  • 这是我对那个问题的回答的副本,在我稍作修改以插入问题的关键点后:标题包含两行

编辑:我根据评论中发布的规范修改了代码:每个文件中有三行的标题,但只有第三个必须包含在输出中。

@echo off
setlocal enabledelayedexpansion

cls

REM cd C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\

set "header3="
(for %%A in (*.csv) do (

   if not defined header3 (
      (set /p "header1=" & set /p "header2=" & set /p "header3=") <%%A
      echo !header3!
   )

   more +3 %%A

)) > Combined.txt
  • 这是当这个程序使用上面的数据运行时生成的 Combined.txt 文件:

.

[ Row : Header ],,,,,,,,,
ContractNum,ProgramNum,CustomerNum,TierNum,StartDate,EndDate,DateCreated,CreatedBy,DateUpdated,UpdatedBy
00032116,21238,60304PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14
00032116,21238,81790PRMI,3,2014-05-02,2017-09-30,Administrator,Administrator,2016-02-29 10:46:14,2016-02-29 10:46:14
00024067,15562,9942PRMI,1,2014-09-16,2016-12-31,gintgUser,gintgUser,2016-02-21 05:59:43,2016-02-21 05:59:43

如您所见,输出与您想要的相同。

编辑:我无法测试修改,因为发布的输入文件包含与真实文件相同的数据...

  • 您应该跟进您发布的问题,而不是发布与之前问题完全相同的新问题。
  • 您应该更清楚地描述您的问题并发布示例数据。

【讨论】:

  • @aanici:正如你所说,我需要将我的疑问重新发布为一个不同的问题,我也做了同样的事情。如果这违反了我不知道的论坛规则,我很抱歉,我应该删除这个问题吗?另外,感谢您的帮助。实际上是三个标题行,第一个是空格,后面是两行标题和第 4 行的数据。我必须跳过前两行并从第三行中选择标题我已经尝试了以下{for /f "tokens=* skip=2" %%A in (C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\dirfiles. txt) 做 ( } 但它不起作用
  • 1.从未说过你需要重新发布一个不同的问题!我说:“发布您文件的一小部分...请编辑问题,不要在 cmets 中发布其他数据!”(您可以重读 my comment)。只是放弃一个没有进一步答复的开放式问题(如对话)是不好的网络礼仪。
  • 2. 也许你还没有意识到这个问题的核心是关于标题:标题有三行,只有第三行必须包含在输出。但是,如此重要的信息不会出现在问题中,而是出现在 cmets 中(“请不要在 cmets 中发布其他数据!”)。您应该在 此问题 中包含该信息(NOT 在新问题中)。如何? “编辑问题”。如何?通过问题下方出现的“编辑”灰色链接,紧接在windowsbatch-file 蓝色标签下方(在“分享”和“关闭”之间)。
  • 3. 如果您的数据文件有三行标题(第一行是空的),为什么这些行没有出现在您的帖子中输入文件?发布示例数据的目的是我们可以访问您拥有的相同数据。如果您在发布数据时对其进行了修改,那么发布的数据将毫无用处... 4. 我不明白您为什么要问我有关执行 NOTfor /f 命令/i> 出现在我的代码中!无论如何,如果您只是说“实际上是三个标题行”,为什么要使用“skip=2”? (“三”不是“2”)。 5. 我根据 new 标头规范修改了我的解决方案。
  • 感谢这些 cmets 将记住它们,并且不会重复它们 :) 。该解决方案也有效。我认为空白被某人编辑了。我会添加那些。谢谢您的帮助
【解决方案2】:

不需要包含 CSV 文件列表的临时文件,您可以通过标准 for 循环和嵌套 for /F 循环读取和组合它们,使用其 skip 选项摆脱标题(假设标题始终是单行)。初始标头可以取自另一个在第一次迭代时被破坏的 for/for /F 循环构造:

> "C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv" (
    for %%F in ("C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\ContractEligibility_*.csv") do (
        for /F "usebackq eol=| delims=" %%L in ("%%~F") do (
            echo(%%L
            goto :LEAVE
        )
    )
)
:LEAVE
>> "C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv" (
    for %%F in ("C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\ContractEligibility_*.csv") do (
        for /F "usebackq skip=1 eol=| delims=" %%L in ("%%~F") do (
            echo(%%L
        )
    )
)

如果您需要 CSV 文件的特定排序顺序,则需要另一个 for /F 循环而不是标准的 for 循环来解析 dir /B 命令的输出来完成这项工作。以下示例采用两行标题,然后将文件从最旧到最新的修改日期排序:

> "C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv" (
    set "FLAG="
    for %%F in ("C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\ContractEligibility_*.csv") do (
        for /F "usebackq eol=| delims=" %%L in ("%%~F") do (
            echo(%%L
            if defined FLAG goto :LEAVE
            set "FLAG=#"
        )
    )
)
:LEAVE
>> "C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\Combined.csv" (
    for /F "eol=| delims=" %%F in ('
        dir /B /A:-D /O:D /T:W "C:\Users\kartikeya.avasthi\Desktop\Batch_Scripts\ContractEligibility_*.csv"
    ') do (
        for /F "usebackq skip=2 eol=| delims=" %%L in ("%%F") do (
            echo(%%L
        )
    )
)

【讨论】:

  • 感谢以上内容,有什么方法可以从第三行开始在第一个 for 循环中获取标题。我也是社区的新用户,非常感谢您提供的格式更新。
  • @kartikeya_aj,所以标题跨越第 1 行和第 2 行(如您的示例数据所示)?见我的edit(即将推出)...
  • 好吧...您问题中的示例显示了两行/行,因此调整我的答案没有意义...无论如何,您知道该怎么做;你也可以使用一个计数器,比如COUNT,在第一个循环中递增,比如set /A COUNT+=1,然后离开循环条件,比如if !COUNT! EQU 3 goto :LEAVE;正如你所看到的 (!COUNT!) 你需要延迟扩展然后......
  • 感谢您的解决方案
【解决方案3】:

如果您想安装awk - Unix/Linux 中最方便的程序之一 - 您的任务将变得非常简单。它适用于 Windows,来自 here

那么你可以使用:

awk  'NR<3 || FNR>2'  *.csv

要解释该命令,您需要知道NRNumber of the Record(即行号),它从第一个文件的第一条记录/行开始,然后随着每条记录递增,所以对于第一个文件的前两条记录,它将小于 3。另一方面,FNRFile Number of Record,它是相同的,但随着每个新文件的打开,它会重置为一个,因此每个文件的前两条记录将小于 2。

所以,总而言之,命令说... “如果它是所有输入文件的前两行之一,或者如果它超过任何文件的第 2 行,则打印任何行。 "

请注意,您可能需要在 Windows 上将单引号替换为双引号。

请注意,如果您要下载gawk,它的工作原理与本示例中的awk 相同。

【讨论】:

    猜你喜欢
    • 2015-05-05
    • 2021-05-13
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2014-03-31
    • 2020-05-08
    • 1970-01-01
    相关资源
    最近更新 更多