2013-03-27 86 views
0

如何将文本文件转换为固定长度的文件:批量文件转换逗号分隔固定长度

这里是我的代码的尝试和示例文本文件。

del answer.txt 

@ECHO on 
@setlocal ENABLEDELAYEDEXPANSION 
cls 
set space= 
set var 

:: loop through records 
for /f "tokens=1-6 skip=1 delims=," %%a in (comma3.txt) do (
echo tokens %%a %%b %%c %%d %%e %%f 
set var=%%a%space%%%b%space%%%c%space%%%d%%e%%f 
echo var %var% 
echo %var% >> answer.txt 
) 
endlocal 
pause 

输入:

1116559,P1303251287,20130325225906CD,13013822,1,0000 
1104220,P1303250282,20130325070119CD,,1,0000 
1064743,P1303251094,20130325191600CD,,0,0000 
1100819,P1303250369,20130325091722CD,,0,0000 
1101405,P1303250051,20130325010740CD,,0,0000 

所需的输出:

1116559 P1303251287 20130325225906CD 13013822 1 0000 
1104220 P1303250282 20130325070119CD    1 0000 
1064743 P1303251094 20130325191600CD    0 0000 
1100819 P1303250369 20130325091722CD    0 0000 
1101405 P1303250051 20130325010740CD    2 0000 

注:

set var命令不存储变量。

帮助非常感谢!

+0

你有PowerShell的安装? Powershell可以格式化类似于'printf'的文本。如果PowerShell是不是一种选择,它可能仍然是可能的空间,填补了一些变量来模拟固定宽度列。 – rojo 2013-03-28 01:59:35

+0

我相信我有PowerShell的,但从来没有做过任何事的。如果它是一个简单,可靠的方案,我将开始在该产品educationg自己。我发现这些网站经常引用它。 – Stumped 2013-03-28 14:38:54

+0

然后看到我的答案。 (: – rojo 2013-03-28 15:06:27

回答

0
@ECHO off 
SETLOCAL 
set columnsizes=10 14 19 11 4 4 
DEL answer.txt 2>nul 

:: loop through records 
for /f "delims=" %%a in (comma3.txt) do (
SET "result=" 
SET line=%%a 
CALL :process %columnsizes% 
) 
ECHO.====================================== 
TYPE answer.txt 
ECHO.====================================== 
PAUSE 
GOTO :eof 

:process 
REM IF "%1"=="" echo %result%>>answer.txt ECHO %result%&GOTO :eof 
IF "%1"=="" echo %result%>>answer.txt&GOTO :eof 
SET "column=" 
:colloop 
IF NOT DEFINED line GOTO endcol 
SET ch1=%line:~0,1% 
SET line=%line:~1% 
IF NOT "%ch1%"=="," SET column=%column%%ch1%&GOTO colloop 
:endcol 
SET column=%column%       x 
CALL SET result=%result%%%column:~0,%1%% 
SHIFT 
GOTO process 

这应该破解的难题。

FOR loop将每行的内容轮流分配到line。例程:process分析aline并逐个字符地构建每个列,直到找到逗号。然后它在行的末尾添加了大量空格 - 在下一个语句中“x”将被删除,并且显示行中的尾随空格(以及一些编辑器将它们自动排除),这是一个棘手的难题。

CALL SET行使用解析器特征。假设result目前abcdcolumn123 ..manyspaces.. x和%1是5。解析器处理由通过它的当前值替换任何%VAR%的线,然后调用它,所以所谓的是

SET result=abcd +%+%column:~0,5+% 

而不+当然 - 他们将展示解析器如何看待代码。

因此,整齐地摆脱不必要的尾随空间和在column x; SHIFT删除提供给:process的参数列表中的第一个元素,并处理下一列,直到完成所有操作并且没有参数。写出result,我们就完成了...

+0

那么这是非常密切的。然而,我answet.txt文件都有每行的复制与ECHO它们之间insterted词结果:1116559 P1303251287 20130325225906CD 13013822 1 0000 ECHO 1116559 P1303251287 20130325225906CD 13013822 1 0000 ...我怀疑它与环回的最后一行“GOTO过程”,这导致的结果将被添加到它自身做 – Stumped 2013-03-28 17:08:57

+0

嗯,我REM'd指出,是造成问题的线 - 现在正确的路线跟随它额外的ECHO ...在证明测试期间,在线应该回到屏幕上,但是在假期前应该已经过了'&'。现在修复。 – Magoo 2013-03-28 18:10:25

+0

这是一个甜蜜的解决方案!我非常感谢你的努力。感谢其他人提出他们的建议。我也正在着手Powershell自学教程。 – Stumped 2013-03-28 19:22:27

0
@ECHO on 
@setlocal ENABLEDELAYEDEXPANSION 
cls 

:: loop through records 
for /f "tokens=1-6 delims=," %%a in (comma3.txt) do (
set var=%%a %%b %%c %%d %%e %%f 
REM The double comma is a problem without a good solution 
REM  so if the last token is null, drop it and indent. 
if '%%f' == '' set var=%%a %%b %%c   %%d %%e 
REM !'s should be used with ENABLEDELAYEDEXPANSION 
echo !var! >> answer.txt 
) 
endlocal 
1

下面是一个解决所有问题的方法。 :)

>answer.txt powershell "Get-Content comma3.txt | %{'{0,-10}{1,-14}{2,-19}{3,-11}{4,-4}{5}' -f $_.split(',')}" 

如果你把这个变成一个批处理脚本,确保在该行与%%更换%

answer.txt的内容:

1116559 P1303251287 20130325225906CD 13013822 1 0000 
1104220 P1303250282 20130325070119CD    1 0000 
1064743 P1303251094 20130325191600CD    0 0000 
1100819 P1303250369 20130325091722CD    0 0000 
1101405 P1303250051 20130325010740CD    0 0000 

一个微弱的解释:

有人更舒适的使用PowerShell大概可以解释这个比我更好,因为它采取了一堆试验和对我来说构成这条线是错误的。但基本上,按照我的理解,它的意思如下:

  • 发送PowerShell命令的输出answer.txt
  • comma3.txt
  • %for each line
  • 返回类似格式化线速记到printf "%-10s %-14s %-19s etc."使用line.split(",")作为字符串参数

可能有一个Write-Content命令powershell,但只是让命令控制台重定向powershell的输出更容易。如果你正在处理非常大的csv文件,并且这个命令的工作速度太慢,Write-Content可能值得研究。

+0

加载Powershell。将这个aboe行复制到PS控制台并试图运行它,但rcvd语法错误。基本上用answer.txt引导暂停进程... – Stumped 2013-03-28 17:29:37

+0

@Stumped - 这是因为它是一个'cmd'控制台命令,而不是'powershell' shell命令。只需打开一个'cmd'窗口并在命令提示符处粘贴该行。该行基本上启动'powershell',执行一个命令,并立即退出。从'cmd'提示符下,你可以通过在这里调用'powershell' cmdlet''来运行'powershell' cmdlet,但仍然在'cmd'环境中。那有意义吗? – rojo 2013-03-28 17:32:04

+0

TADA!像魅力一样工作。我放弃了answer.txt之前的'>'。我认为它是显示的一部分,我不认为PS命令会以目标文本文件的名称开始。这吸盘的作品!这将是我的PS自学教程的基础。 – Stumped 2013-03-28 19:26:59

0

扩展在Rojos答案,我创建了一个Excel宏所使用的线1列宽,导出的文件为CSV,被叫PowerShell来转换为分隔的,像这样的空间:

runCommand = "echo Please Wait . . . " 

“更改为正确的驱动器和目录:

runCommand2 = Left(SaveDirectory, 2) <br> 
runCommand3 = "cd " & SaveDirectory<br> 

“删除“是Excel可能会插入

runCommand7 = "powershell ""(get-content '" & SaveDirectory & "\" &  SaveName & ".csv" & "') -replace('""""','') | out-file '" & SaveDirectory & "\" & SaveName & "2.csv'""" 
马克

“循环通过对电子表格的第一行单元格与正确的列宽

runCommand4 = "powershell ""Get-Content '" & SaveName & "2.csv'" & " | %{'" 

x = 1 
c = 0 

Do Until Cells(1, x) = "" 
    runCommand4 = runCommand4 & "{" & c & ",-" & Cells(1, x).Value & "}" 
    x = x + 1 
    c = c + 1 

Loop 

runCommand4 = runCommand4 & "' -f $_.split(',')} | Out-File Answer2.txt""" 

runCommand5 = "cls" 
runCommand6 = "pause" 

删除与列宽行,使他们不会被导出创建PowerShell命令:

Rows("1:1").Select 
Selection.Delete Shift:=xlUp 

查找和替换任何逗号和制表符,因为这些可能会导致问题:

Cells.Replace What:=",", Replacement:="", LookAt:=xlPart, SearchOrder:= _ 
    xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False 
Cells.Replace What:=Chr(9), Replacement:="", LookAt:=xlPart, SearchOrder:= _ 
    xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False 

将工作簿另存为CSV:

ActiveWorkbook.SaveAs Filename:=SaveDirectory & "\" & SaveName, FileFormat _ 
    :=xlCSV, CreateBackup:=False 

通过所有的命令到CMD

Call Shell("C:\Windows\System32\cmd /c" & runCommand & "&" & runCommand2 & "&" & runCommand3 & "&" & runCommand7 & "&" & runCommand4 & "&" & runCommand6, vbNormalFocus) 

ActiveWorkbook.Close 

这可能是一个方便的解决方案,如果您导入CSV脱颖而出。