markierte CSV-Dateien horizontal zusammenfügen

German support forum

Moderators: Hacker, Stefan2, white

Post Reply
ltec
Junior Member
Junior Member
Posts: 9
Joined: 2014-08-23, 15:27 UTC

markierte CSV-Dateien horizontal zusammenfügen

Post by *ltec »

Hallo hilfsbereites TC-Forum,

ich möchte mehrere im TC markierten CSV-Dateien horizontal zu einer neuen CSV-Datei zusammensetzen.
Die erste gibt die Zeilenanzahl vor. Sind in den anderen mehr Zeilen enthalten werden diese ignoriert. Sind allerdings weniger Zeilen enthalten soll der Wert mit "0" gesetzt werden.
Ziel ist eine vollständig mit Werten gefüllte CSV-Datei.

Die Suche nach geeigneten Tools führt meist zum Anhängen von Dateien (vertikal) oder es sind Programme, die sich nicht auf viele Dateien anwenden lassen.

Ich bin für jeden Hinweis dankbar.

Viele Grüße
Frank
User avatar
Dalai
Power Member
Power Member
Posts: 9975
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Hast du noch mehr solcher Anforderungen? Dann lohnt sich wohl mal ein genauerer Blick auf AutoIt (oder auch eine andere Skriptsprache). Machbar ist das damit, aber es erfordert natürlich etwas Verständnis fürs Programmieren.

Andere Frage: Ist es zwingend, dass die Dateien horizontal zusammengeführt werden? Kannst du die Tabelle/Matrix nicht einfach transponieren (Zeilen werden zu Spalten und umgekehrt)? Wenn das möglich wäre, könnte man Tools verwenden, die vertikales Zusammenführen unterstützen.

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
Stefan2
Power Member
Power Member
Posts: 4281
Joined: 2007-09-13, 22:20 UTC
Location: Europa

CONCATenate text files side-by-side.vbs dateien horizontal

Post by *Stefan2 »

Zwei Textdateien horizontal zu einer Neuen zusammenfügen:


CONCATenate text files side-by-side.vbs

Code: Select all

'CONCATenate two text files side-by-side.vbs
'The amount of lines in File1 indicate the to be done iterations.
'If File2 has fewer lines, a zero is printed out instead for each missed F2 line.
'Usage:  cscript //nologo concat.vbs file1.txt file2.txt file3-out.txt

  Const ForReading = 1, ForWriting = 2, ForAppending = 8
  Dim fso, arg, File1, File2, File3, Delim, line1, line2
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set arg = WScript.Arguments
  Set File1 = fso.OpenTextFile(arg(0), ForReading)
  Set File2 = fso.OpenTextFile(arg(1), ForReading)
  Set File3 = fso.CreateTextFile(arg(2), ForWriting)
   Delim = " "
  'Delim = ";"
  'Delim = vbTAB
  Do While Not File1.AtEndOfStream
      line1 = File1.ReadLine
      If not (File2.AtEndOfStream) Then
          line2 = File2.ReadLine
      Else
          line2 = "0"
      End If
    outarray = outarray & line1 & Delim & line2 & vbCRLF
  Loop
  File3.write outarray : File1.close : File2.close : File3.close


Usage in DOS-Box console:

concat.vbs   file1.txt   file2.txt   file3-out.txt


 
ltec
Junior Member
Junior Member
Posts: 9
Joined: 2014-08-23, 15:27 UTC

Post by *ltec »

Hallo Dalai, hallo Stefan,
ich kann mich nur wiederholen: DANKE!
Soviel Hilfe an einem Sonntag ... liegt es am schlechtem Wetter?

@Dalai:
Nein, das sind (waren) mich schon länger störende Probleme, zu denen ich mir ein umständliches WorkAround gebastelt habe.
Prinzipiell würde mich das Programmieren schon reizen, ich bin aber eben nur Anwender und kann maximal eine kleine Änderung vornehmen. Dabei wird es wohl leider aus Zeitgründen auch bleiben müssen. Umso dankbarer bin ich deshalb für eure professionelle Hilfe.

@Stefan:
Es funktioniert prima. Um ehrlich zu sein, ich wusste gar nichts von VB-Scripts in einer DOS-Box. Da meine speziellen CSV-Dateien immer mit Semikolon getrennt sind, habe ich lediglich das Trennzeichen geändert.
Außerdem sind immer 3 Spalten vorhanden, deshalb habe ich aus der 0 eine 0;0;0 gemacht. Das ist für dich wahrscheinlich gemurkst, sorry, hilft mir aber weiter - vielen Dank.
Ich habe das Script auf einen TC-Button gelegt, das geht nur bedingt, da ich nicht weiss, wie man die (2) markierten Dateinamen da rein bekommt.
Bombig wäre, wenn alle (>2) markierten Dateien vom Script bearbeitet werden (Ausgabedateiname kann immer gleich bleiben).

Viele Grüße
Frank
User avatar
Dalai
Power Member
Power Member
Posts: 9975
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

ltec wrote:Ich habe das Script auf einen TC-Button gelegt, das geht nur bedingt, da ich nicht weiss, wie man die (2) markierten Dateinamen da rein bekommt.
Ganz einfach:

Code: Select all

TOTALCMD#BAR#DATA
E:\concat.vbs
%S2 file3-out.txt

CSVs zusammenführen
e:\

-1
Bombig wäre, wenn alle (>2) markierten Dateien vom Script bearbeitet werden (Ausgabedateiname kann immer gleich bleiben).
Tja, klar wäre das schön. Aber das dafür notwendige Skript ist recht aufwendig zu schreiben.

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
Dalai
Power Member
Power Member
Posts: 9975
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Hier mal mein Versuch, die Sache für eine beliebige Zahl von Dateien zu ermöglichen:

Code: Select all

; markierte CSV-Dateien horizontal zusammenfügen
; http://ghisler.ch/board/viewtopic.php?t=41000

#include <File.au3>
;#include <Array.au3>

Opt("MustDeclareVars", 1)

global const $OUTFILE = @TempDir & "\concatenated.csv"
global const $DELIM = ";"

;------------------------------------------------------------------------------

global const $FILEMODE_READ = 0, $FILEMODE_APPEND = 1, $FILEMODE_WRITE = 2

global $i, $line, $FileList, $FileListArray, $hFile, $FileHandleArray[1], $FileLineArray[1]

if NOT $CmdLine[0] > 0 then Exit

$FileList = $CmdLine[1]

if _FileReadToArray($FileList, $FileListArray) then
    ReDim $FileHandleArray[$FileListArray[0]+1]
    ReDim $FileLineArray[$FileListArray[0]+1]
    for $i=1 to UBound($FileListArray)-1
        $FileHandleArray[$i] = FileOpen($FileListArray[$i], $FILEMODE_READ)
    Next
    $hFile = FileOpen($OUTFILE, $FILEMODE_WRITE)
    if $hFile > 0 then
        While 1
            $line = ""
            for $i=1 to UBound($FileListArray)-1
                $FileLineArray[$i] = FileReadLine($FileHandleArray[$i])
                if (@error <> 0) then
                    if ($i == 1) then
                        ExitLoop 2
                    else
                        $FileLineArray[$i] = 0
                    EndIf
                EndIf
                $line &= $FileLineArray[$i] & $DELIM        
            Next
            FileWriteLine($hFile, $line)
        WEnd
        FileClose($hFile)
    EndIf
    for $i=1 to UBound($FileListArray)-1
        FileClose($FileHandleArray[$i])
    Next
    $FileLineArray = 0
    $FileHandleArray = 0
EndIf
Weiß nicht genau, ob's richtig ist. Probier's mal aus.

Ergänzung: Das Skript erwartet die Übergabe eines Dateinamens, in der eine Liste von CSV-Dateien steht. Also für den Button oder Startermenü-Eintrag im TC wieder %L verwenden.

MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
ltec
Junior Member
Junior Member
Posts: 9
Joined: 2014-08-23, 15:27 UTC

Post by *ltec »

Hallo Dalai,

funktioniert - super!

Fast am Ziel:
In meinen speziellen CSV-Dateien sind immer 3 Spalten vorhanden.
D.h. bei den "leeren" Dateien sollte nicht wie jetzt eine "0" eingesetzt werden sondern "0;0;0".
Für dich bestimmt kein Problem (ich habe es mal versucht, kam aber nur Blödsinn raus).

Viele Grüße

Frank
User avatar
Dalai
Power Member
Power Member
Posts: 9975
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

ltec wrote:In meinen speziellen CSV-Dateien sind immer 3 Spalten vorhanden.
D.h. bei den "leeren" Dateien sollte nicht wie jetzt eine "0" eingesetzt werden sondern "0;0;0".
Die Änderung ist in Zeile 38 zu machen, d.h. aus

Code: Select all

if ($i == 1) then
    ExitLoop 2
else
    $FileLineArray[$i] = 0
EndIf
wird

Code: Select all

if ($i == 1) then
    ExitLoop 2
else
    $FileLineArray[$i] = StringFormat("0%s0%s0", $DELIM, $DELIM)
EndIf
MfG Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
Stefan2
Power Member
Power Member
Posts: 4281
Joined: 2007-09-13, 22:20 UTC
Location: Europa

CONCATenate ALL selected TEXT files side-by-side.vbs

Post by *Stefan2 »

Ohh, bereits erledigt ;-)

Ich habe mich heute morgen ebenfalls an diesem Thema versuch und es in VBScript realisiert.

Just for the record:

Code: Select all


REM http://ghisler.ch/board/viewtopic.php?p=287780#287780
REM    _____                          _         _    _               
REM   |  __ \                        (_)       | |  (_)              
REM   | |  | |  ___  ___   ___  _ __  _  _ __  | |_  _   ___   _ __  
REM   | |  | | / _ \/ __| / __|| '__|| || '_ \ | __|| | / _ \ | '_ \ 
REM   | |__| ||  __/\__ \| (__ | |   | || |_) || |_ | || (_) || | | |
REM   |_____/  \___||___/ \___||_|   |_|| .__/  \__||_| \___/ |_| |_|
REM                                     | |                          
REM                                     |_|                          
REM Total Commander VBScript "CONCATenate ALL selected TEXT CVS(!) files side-by-side.vbs" by Stefan, 2014-08-25, v0.01
REM This script use a very simple logic and have no error handling for different amount of lines:
REM   The amount of lines in the FIRST file indicates the amount of VALID lines in the result file.
REM   If the next files have more lines, they may be printed more to the left of the concatenated lines.
REM   If the next files have fewer columns, a zero is printed out instead for each missed column.
REM   So be sure your files have the same amount of lines.
REM Usage:  cscript //nologo concat.vbs InputList.txt  ResultFile.txt 
REM         InputList.txt contains all files to become concatenated, one on each line.
REM         ResultFile.txt will hold the concatenated result.
REM 
REM     NO GUARANTEE GRANTED  -  TEST WITH TEST FILES FIRST  -  AND ALWAYS HAVE A BACKUP OF YOUR FILES
REM
REM Use from a Total Commander Button:
REM Command:   path\to\this\VBScript.vbs
REM Parameter: %L ResultFile.txt  
REM ( "%L" is a temp file with all selected files, see TC help for more)
REM (ResultFile.txt is the name of the output file in the current directory, use "C:\Temp\ResultFile.txt" for a full path)
REM 

'  // Test:

'  // a.txt 
'  // atxt; eins; zwei
'  // atxt; drei; vier
'  // atxt; fünf; sechs
'  // atxt; sieben; line4 is to much

'  // b.txt
'  // btxt; one; two
'  // btxt; three; four
'  // btxt; five; six

'  // c.txt
'  // ctxt; 1
'  // ctxt; 2
'  // ctxt; 3

'  // d.txt
'  // dtxt
'  // dtxt
'  // dtxt
'  // dtxt line4 is to much

'  // RESULT.txt
'  // atxt; eins; zwei; btxt; one; two; ctxt; 1; 0; dtxt; 0; 0
'  // atxt; drei; vier; btxt; three; four; ctxt; 2; 0; dtxt; 0; 0
'  // atxt; fünf; sechs; btxt; five; six; ctxt; 3; 0; dtxt; 0; 0
'  // atxt; sieben; dtxt line4 is to much; dtxt line4 is to much; 0; 0

REM
REM    _   _                    _____        _    _    _                    
REM   | | | |                  /  ___|      | |  | |  (_)                   
REM   | | | | ___   ___  _ __  \ `--.   ___ | |_ | |_  _  _ __    __ _  ___ 
REM   | | | |/ __| / _ \| '__|  `--. \ / _ \| __|| __|| || '_ \  / _` |/ __|
REM   | |_| |\__ \|  __/| |    /\__/ /|  __/| |_ | |_ | || | | || (_| |\__ \
REM    \___/ |___/ \___||_|    \____/  \___| \__| \__||_||_| |_| \__, ||___/
REM                                                               __/ |     
REM                                                               |___|
REM      
strTCtempList = Wscript.arguments.Item(0) ' The TC temp file due to the "%L" parameter
strResultFile = Wscript.arguments.Item(1) ' The output file due to the second parameter in TC command
strDelim = "; "                           ' Separate the joined lines by this sign, e.g. Space: " ",
                                          '  or Semicolon: ";", or Tab: vbTab (should be same as other used delims)
strMissed = "0"                           ' Fill up missed columns at the end with this string
REM =================================================================
REM =================================================================
REM =================================================================
REM    _____  _                 _____             _       
REM   |_   _|| |               /  __ \           | |      
REM     | |  | |__    ___      | /  \/  ___    __| |  ___ 
REM     | |  | '_ \  / _ \     | |     / _ \  / _` | / _ \
REM     | |  | | | ||  __/     | \__/\| (_) || (_| ||  __/
REM     \_/  |_| |_| \___|      \____/ \___/  \__,_| \___|    (Don't touch)
REM
Const ForReading = 1, ForWriting = 2, ForAppending = 8 
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSC = CreateObject("WScript.Shell")
intProcessedLinesCount = 0
intDetectedDelimsAmount = "NotSetYet"
Dim arrFileLines()
If  FSO.FileExists(strTCtempList) Then
  Set oListOfSelectedFiles = FSO.OpenTextFile(strTCtempList,ForReading)
  Do Until oListOfSelectedFiles.AtEndOfStream
    intProcessedLinesCount = intProcessedLinesCount + 1
    vFullName  = oListOfSelectedFiles.ReadLine
    intIteration = -1
    Set oCurrSelFile = FSO.OpenTextFile(vFullName, ForReading)
    Do Until oCurrSelFile.AtEndOfStream
      intIteration = intIteration + 1
      On Error Resume Next
      If arrFileLines(intIteration) = "" Then  Redim Preserve arrFileLines(intIteration)
      On Error Goto 0
      strCurrLine = oCurrSelFile.ReadLine
      intCurrDelimsAmount = UBound(split(strCurrLine, strDelim))
      If intDetectedDelimsAmount = "NotSetYet" Then 
        ' Detect need delim amount from first line on first file
        intDetectedDelimsAmount = intCurrDelimsAmount
      End IF
      If intCurrDelimsAmount < intDetectedDelimsAmount Then
        ' Complete lines with less delims to detected amount
         For intTemp = intCurrDelimsAmount to intDetectedDelimsAmount -1
            strCurrLine = strCurrLine & strDelim & strMissed
         Next
      End If
      arrFileLines(intIteration) = arrFileLines(intIteration) & strCurrLine & strDelim
    Loop
    oCurrSelFile.Close
  Loop
  oListOfSelectedFiles.Close
Else
  MsgBox "Input file strTCtempList not found. Check your TC button parameters"
End If
REM =================================================================
REM    _____                    _  _               ____          _                  _   
REM   |  __ \                  | || |             / __ \        | |                | |  
REM   | |__) | ___  ___  _   _ | || |_   ______  | |  | | _   _ | |_  _ __   _   _ | |_ 
REM   |  _  / / _ \/ __|| | | || || __| |______| | |  | || | | || __|| '_ \ | | | || __|
REM   | | \ \|  __/\__ \| |_| || || |_           | |__| || |_| || |_ | |_) || |_| || |_ 
REM   |_|  \_\\___||___/ \__,_||_| \__|           \____/  \__,_| \__|| .__/  \__,_| \__|
REM                                                                  | |                
REM                                                                  |_|   
REM =================================================================
'MsgBox "All "&intProcessedLinesCount&" Done!"
REM =================================================================
 For L = 0 to Ubound(arrFileLines)
    strOutline = left(arrFileLines(L), len(arrFileLines(L)) - len(strDelim)) ' remove trailing delim
    arrOutarray = arrOutarray & strOutline & vbCRLF
 Next
 REM =================================================================
 overwrite = true
 Set oOutfile = FSO.CreateTextFile(strResultFile, overwrite ) 
 oOutfile.write arrOutarray
 oOutfile.close
 REM =================================================================
  WSC.run "notepad " & strResultFile
 'WSC.run "excel " & strResultFile
REM =================================================================<EOF>




Ich habe es auch mit unterschiedlicher Zeilenanzahl ausprobiert, aber mangels Zeit meine Versuche abgebrochen.


 
ltec
Junior Member
Junior Member
Posts: 9
Joined: 2014-08-23, 15:27 UTC

Post by *ltec »

Hallo Dalai, hallo Stefan,

@Dalai: funktioniert prima

@Stefan:
Du wolltest noch einen drauf legen und die Anzahl der Spalten ermitteln, um die Hilfslösung "0;0;0" zu umgehen - oder täusche ich mich?
Da scheint aber was schief zu laufen, es kommen gar keine "0" (strMissed) in die Ausgabedatei. Ansonsten klappt es mit mehreren Datein einwandfrei.

Ich tue mich schon etwas schwer, den Fehler zu nennen, da ich selbst keinen blassen Schimmer von dem habe, was ihr da macht (um mir zu helfen!).

Viele Grüße
Frank
Post Reply