2013-03-27 27 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脫穎而出。

相關問題