批处理文件将逗号分隔为固定长度

时间:2013-03-27 21:54:58

标签: batch-file text-files

如何将文本文件转换为固定长度的文件:

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

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命令不存储变量。

非常感谢帮助!

4 个答案:

答案 0 :(得分: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(",")的格式化行

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

答案 1 :(得分: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

答案 2 :(得分: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循环依次将每行的内容分配给line。例程:process分析aline并逐个字符地构建每个列,直到找到逗号。然后它在行的末尾添加了大量的空格 - “x”将在下一个语句中被删除,并且在行上显示尾随空格(并且一些编辑将它们自行抛弃)是一个小问题

CALL SET行使用解析器特征。假设result当前为abcdcolumn123 ..manyspaces.. x且%1为5.解析器通过将任何%var%替换为其当前值来处理该行,然后调用它,那么CALLed是什么

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

当然没有+ s - 它们是为了显示解析器如何看到代码。

这样可以巧妙地减少不需要的尾随空格和column中的x; SHIFT从提供给:process的参数列表中删除第一个元素,并处理下一列,直到完成所有操作并且没有剩下参数。写出result,我们就完成了......

答案 3 :(得分:0)

扩展Rojos的答案,我创建了一个使用第1行的列宽的excel宏,将文件导出为csv,调用powershell转换为空格,如下所示:

runCommand = "echo Please Wait . . . "

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

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

&#39;删除&#34; excel可以插入的标记

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

&#39;循环遍历电子表格第一行中的单元格以创建具有正确列宽的powershell命令

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"

删除具有列宽的行,以便不导出它们:

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导入excel,这可能是一个方便的解决方案。