通过批处理从csv文件中删除一些列和行

时间:2015-01-22 00:15:57

标签: batch-file

我正在尝试创建一个批处理文件,该文件将编辑.csv并删除第一列以及文件中包含的任何摘要行。但是,我对编写批处理文件还是比较新的,所以我不确定启动它的最佳方法,如果你可以包含代码如何工作的基本解释,那将是很好的,所以我可以自我维持未来!

,Type,Date,Num,Name,Memo,Member,Clr,Split,Alias,Value,Balance
ABB - Egypt,,,,,,,,,,,
ElAin EL-Sokhna,,,,,,,,,,,
,Invoice,09-06-10,12005,ABB - EL-Sokhna,,Accounts Receivable,,Training Income,15000,,15000
,Invoice,09-14-11,12005,ABB - EL-Sokhna,“ElAin EL-Sokhna“ Trainer for OTS Application: First two weeks,Training Income,,Accounts,,150001,0
Total ElAin EL-Sokhna,,,,,,,,,241194,210400,301794
ABB - Egypt - Other,,,,,,,,,,,

此文件有各种迭代,因为它们来自月度报告,我需要删除第一个(空)列,以及任何看起来像ABB - Egypt,,,,,,,,,,,Total ElAin EL-Sokhna,,,,,,,,,241194,210400,301794

所以输出应该是:

Type,Date,Num,Name,Memo,Member,Clr,Split,Alias,Value,Balance
Invoice,09-06-10,12005,ABB - EL-Sokhna,,Accounts,,Training Income,15000,,15000
Invoice,09-14-11,13002,ABB - EL-Sokhna,“ElAin EL-Sokhna“ Trainer for OTS Application: First two weeks,Training Income,,Accounts,,150001,0

感谢您的投入!

编辑:我的OP似乎不够清楚(对不起,第一次来这里)。

此处需要执行两个流程,在每个文件中必须删除第一列,并且需要删除标题行ABB - Egypt,,,,,,,,,,,或摘要行Total ElAin EL-Sokhna,,,,,,,,,241194,210400,301794的所有行。 / p>

所有需要保留的行都将 填写,例如,Type,Date,Num,Name,Memo,Member,Clr,Split,Alias,Value,Balance,Invoice,09-06-10,12005,ABB - EL-Sokhna,,Accounts Receivable,,Training Income,15000,,15000请注意,如第二行所示,可能存在在它们中有一些缺失的值,所以搜索像“,,”这样的东西是行不通的。

5 个答案:

答案 0 :(得分:1)

一种方法是在将要使用的变量中定义所有规则 findstr。规则必须如下定义:

/c:"String which exclude the line" /c:"Another string which exclude the Line" /c: "etc.."

此规则必须准确无误(他们无法在必须保留的行中找到)。

对于 empty 第一个冒号,您可以使用我在代码中使用

的方式进行替换

,Type=Type ,Invoice=Invoice

Test.bat:

@echo off&cls
setlocal enabledelayedexpansion

Rem The rules   
set $String_To_Search=/c:"ABB - Egypt," /c:"Total ElAin El-Sokhna," /c:"ElAin EL-Sokhna," /c:"ABB - Egypt - Other,"

for /f "delims=" %%a in (test.csv) do (
 set $line=%%a

 Rem the substitutions for the first Column
 set $Line=!$Line:,Type=Type!
 set $line=!$Line:,Invoice=Invoice!

 Rem the test and the ouput if nothing was found
 echo !$Line! | findstr /i %$String_To_Search% >nul || echo !$Line!
))>Output.csv

我使用文件test.csv进行测试。

输出被重定向到Output.csv

答案 1 :(得分:1)

也许这就是你想要的?

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%a in (input.csv) do (
   set "line=%%a"
   if "!line:~0,1!" equ "," echo !line:~1!
)

当问题解释不充分时,我们只能猜出缺失的细节。在这种情况下,我假设你只想要以逗号开头的行,删除它。输出与输出示例相同......

编辑添加了输出示例

Type,Date,Num,Name,Memo,Member,Clr,Split,Alias,Value,Balance
Invoice,09-06-10,12005,ABB - EL-Sokhna,,Accounts Receivable,,Training Income,15000,,15000
Invoice,09-14-11,12005,ABB - EL-Sokhna,“ElAin EL-Sokhna“ Trainer for OTS Application: First two weeks,Training Income,,Accounts,,150001,0

答案 2 :(得分:1)

Batch是一种用于修改文本文件的糟糕语言。有许多特殊情况需要晦涩的知识才能解决问题。你可能有一个似乎做你想要的脚本,然后你的数据中会出现一些皱纹,整个脚本可能需要重新设计。

关于您的具体问题,在我看来,您只想保留以逗号开头的行,这意味着第一列为空。在剩余的行中,您要删除第一个(空)列。

假设您要保留的所有行都没有第二列的空值,那么有一个非常简单的解决方案:

@echo off
>"%~1.new" (for /f "delims=, tokens=*" %%A in ('findstr "^," %1') do echo %%A)
move /y "%~1.new" %1 >nul

脚本期望将文件作为第一个也是唯一的参数传递。因此,如果您的脚本命名为" fixCSV.bat",并且要修改的文件是" c:\ test \ file.csv",那么您将使用:

fixCSV "c:\test\file.csv"

%1扩展为第一个参数的值,%~1是相同的,除了它还会删除任何可能存在或不存在的封闭引号。

FINDSTR命令读取文件并仅写出以逗号开头的行。 FOR / F命令迭代每行输出。 " delims =,tokens = *" options有效地从每一行中删除所有前导逗号,结果在变量%%A中,然后是ECHOed。整个构造括在括号中,stdout被重定向到临时文件。最后,临时文件移动到原始文件的顶部,从而替换它。

如果第二列可能为空,则结果将被破坏,因为它会删除所有前导逗号(在这种情况下都是第1列和第2列)。脚本必须更复杂才能进行补偿。您需要设置一个变量,然后使用延迟扩展来获取子字符串,跳过第一个字符。但延迟扩展将破坏%% A变量的扩展,如果它包含!字符。所以延迟扩张必须打开和关闭。你开始明白我的意思了很多特殊情况。

@echo off
setlocal disableDelayedExpansion
>"%~1.new" (
  for /f "delims=" %%A in ('findstr "^," %1') do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo !ln:~1!
    endlocal
  )
)
move /y "%~1.new" %1 >nul

随着批处理脚本变得越来越复杂,它们变得越来越慢。它可能不是大多数文件的问题,但如果文件非常大(比如数百兆字节),那么它可能会成为一个问题。

我几乎从不使用纯批处理来修改文本文件。相反,我使用了一个名为JREPL.BAT的混合JScript /批处理实用程序。该实用程序是纯脚本,可​​以在XP之后的任何Windows机器上本机运行。 JREPL.BAT能够使用正则表达式替换有效地修改文本文件。正则表达式看起来很神秘,但它们非常值得学习投资。

假设您在PATH中的某处有JREPL.BAT,那么以下命令就是您需要的所有内容:

jrepl "^,(.*)" "$1" /jmatch /f "yourFile.csv" /o -

/ F选项指定要读取的文件。

值为-的/ O选项指定输出应替换原始文件。

/ JMATCH选项指定将每个替换值写入新行。所有其他文本都被删除。

第一个参数是搜索表达式。它匹配以逗号开头的任何行,之后的所有内容都在名为$ 1的变量中捕获。

第二个参数指定替换值,它只是变量$ 1中的捕获值。

答案 3 :(得分:0)

我将从这里开始学习:How can you find and replace text in a file using the Windows command-line environment?

它涵盖了从Windows命令行替换的许多细节以及许多方法,有些只需要Windows内置的内容,有些则需要其他可下载的软件。

Magoo是对的,需要更多标准,但链接页面中可能有足够的信息让您超越主要障碍。

答案 4 :(得分:0)

@ECHO OFF
SETLOCAL
(FOR /f "tokens=*delims=," %%a IN ('findstr /b /l "," q28079306.txt') DO ECHO %%a)>newfile.txt

GOTO :EOF

我使用了一个名为q28079306.txt的文件,其中包含您的测试数据 生成newfile.txt