当前位置: 动力学知识库 > 问答 > 编程问答 >

input - .txt file data into 2 column csv file batch file

问题描述:

Hopefully this is a simple answer. Basically I would like to be able to get the contents of a multiline text file that we will call FileSample.txt. It may contain something along the lines of

Some text sample1 : Extra1

Some text sample2 : Extra2

Some text sample3 : Extra3

Some text sample4 : Extra4

and essentially enter it into a 2-column csv we will call Output.csv. First column should be the filename and the second column should have the contents (including hard returns) of the text file. So essentially the csv should contain this...

FileName,Contents

FileSample.txt,"Some text sample1 : Extra1 Some text sample2 : Extra2 Some text sample3 : Extra3 Some text sample4 : Extra4"

I apologize for the utter confusion here, and the totally noob scripting skills. I am really trying to get this done so I made a solution with powershell.

$Content = Get-Content .\FileSample.txt

$FileName = Get-ChildItem .\FileSample.txt

New-Object PSObject -Property @{

FileName = $FileName.Name

Content = "$Content"

} | Export-Csv .\Output.csv -NoTypeInformation

As much as I did not want to deviate from my initial request of getting this done via a batch file I did manage to get the same results out of this vbscript below without having to resort to using a file saved from ExifTool.

Dim WshShell, oExec

Set WshShell = WScript.CreateObject("WScript.Shell")

Set oExec = WshShell.Exec("%comspec% /c ""D:\EXIFTOOL\exiftool.exe"" test.jpg")

x1 = oExec.StdOut.ReadAll

x2 = Replace(x1, chr(34), chr(34) & chr(34))

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objLogFile = objFSO.CreateTextFile("D:\EXIFTOOL\Output.csv", 1, False)

objLogFile.Write "Filename,"

objLogFile.Write "ExifData"

objLogFile.Writeline

objLogFile.Write chr(34) & "sample6.csv" & chr(34) & ","

objLogFile.Write chr(34) & x2 & chr(34)

objLogFile.Writeline

objLogFile.Close

网友答案:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

@ECHO FileName,Contents

SET FILE=FileSample.txt

SET FIRST=^"%FILE%^",^"
FOR /F "tokens=*" %%l IN (%FILE%) DO @((SET LINE=%%l) & (@ECHO !FIRST!!LINE:^"=^"^"!) & (SET FIRST=))
@ECHO ^"

This echoes the filename, a comma, a double quote, then every line of the file (with double quotes "escaped" by replacing them with a double-double quote—which is necessary if the data in the file may have double quotes in it), followed by a (closing) double quote.

The one limitation I see is that if the file doesn't end with a newline, the closing double quote will effectively add one. If the file does end with a newline, the FOR loop won't process that empty line, and the output will be correct. Overcoming that limitation would probably mean manually counting the lines (an additional loop iterating over the lines) and adding an extra variable and check in the FOR loop. It's too messy for me to think about unless you really, really want that behavior. (At some point, the burden of doing something in batch/CMD becomes worse than depending on PowerShell, VBScript, or some other real programming language to get simple things done.)

If you intended to process numerous files, you could put the last three lines in a "subroutine" (my preference over creating nested FOR loops) and CALL it within a FOR loop that iterates over the files in question.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

@ECHO FileName,Contents

FOR %%f IN (FileSample*.txt) DO CALL :PROCESS_FILE "%%~f"

GOTO :EOF

:PROCESS_FILE
SET "FILE=%~1"

SET FIRST=^"%FILE%^",^"
FOR /F "tokens=*" %%l IN (%FILE%) DO @((SET LINE=%%l) & (@ECHO !FIRST!!LINE:^"=^"^"!) & (SET FIRST=))
@ECHO ^"
EXIT /B

The extra quoting of arguments to :PROCESS_FILE is to handle the case when the file name has a space in it. If it contains a space and you don't quote it, the pieces of the file name will be treated like separate arguments. I suppose you could use %* in that case, but I prefer to quote things to make it clear that I want the data treated as a single unit.

分享给朋友:
您可能感兴趣的文章:
随机阅读: