onlyforu8373
Goto Top

Dateien in Ordner kopieren anhand vom Teil eines Dateinamen

Hallo,

ich bin neu hier im Forum und habe auch gleich schon meine erste Frage.
Ich suche ein Batch-Skript, oder noch eleganter einen Code fürs importieren in Visual Studio (C++) mit einem einfachem Button "z.B. Start" und eleganter Weise zwei Buttons zum Pfad Source und Destination-Pfad ändern, welches meine Dateien anhand des Dateinamens,
erkennt und einen Ordner an Hand des Dateinamens erstellt.

Hintergrund:

Auf einem USB-Stick z.B. F:\ befinden sich gesicherte .LOG und .LGX Dateien, der Dateiname setzt sich zusammen aus Jahr+Monat+Tag.LOG oder .LGX.
Diese Dateien müssen nun MONATSWEISE in einen Ordner verschoben werden, alle Dateien die z.B. den Dateinamen 201609XX tragen, sollen nun in einen noch nicht vorhandenen Ordner 2016/09 (muss gleichzeitig erstellt werden, dabei soll geprüft werden ob der Ordner schon vorhanden ist oder eben nicht, wenn vorhanden Dateien einfach reinkopieren, wenn nicht erstellen und dann kopieren) kopiert werden.
Nach dem ERFOLGREICHEM Kopiervorgang, sollen alle Dateien die vom Skript kopiert wurden, vom USB-Stick, gelöscht werden.

Wäre sehr dankbar über eure Hilfe ! face-smile

Content-ID: 319249

Url: https://administrator.de/contentid/319249

Ausgedruckt am: 25.11.2024 um 06:11 Uhr

131301
131301 27.10.2016 um 10:06:51 Uhr
Goto Top
onlyforu8373
onlyforu8373 27.10.2016 um 10:09:39 Uhr
Goto Top
Am liebsten wäre mir C++, eine Oberfläche habe ich schon gebastelt face-smile
131301
131301 27.10.2016 um 10:14:31 Uhr
Goto Top
onlyforu8373
onlyforu8373 27.10.2016 um 10:24:11 Uhr
Goto Top
Ich denke das ist nicht die Lösung. Der Code listet die Dateinamen auf und erzeugt eine Ausgabe...

Wie gesagt, bin nicht so der C++ Experte.
131301
131301 27.10.2016 aktualisiert um 10:29:27 Uhr
Goto Top
Soll das hier ein Silbertablett sein? So lernst du ja nie was.
Oh man, dann noch die Bestandteile des Dateinamens in der letzten Schleife rausholen schafft doch jeder C Anfänger ...
substr ist dein Freund
http://www.cplusplus.com/reference/string/string/substr/
onlyforu8373
onlyforu8373 27.10.2016 um 10:29:28 Uhr
Goto Top
Nein soll es nicht.
Sorry, aber das ist mein ERSTES C Projekt.
131301
131301 27.10.2016 aktualisiert um 10:32:00 Uhr
Goto Top
substr ist dein Freund
http://www.cplusplus.com/reference/string/string/substr/

Dann setzt du Pfade zusammen prüfst ob er existiert und verschiebst. Alles mit den Standard-Methoden machbar. Man muss nur mal die Doku lesen, gerade wenn man noch nie mit C++ zu tun hatte ist das PFLICHT!
onlyforu8373
onlyforu8373 27.10.2016 aktualisiert um 12:09:48 Uhr
Goto Top
Ich denke ich lasse es erstmal mit einem Skript laufen.
Dann widme ich mich der komplizierteren Aufgaben mit C++.

Kannst du den über mein Skript drüber schauen, welches die Aufgaben erledigt soll?


@echo off && title %~n0 && color 70
setlocal
rem Bitte Quellordner anpassen!
set Quellordner=C:\source\
 
echo. && echo Kopiere alle Dateien um . . . && echo.
for /f "delims=" %%i in ('dir /b %Quellordner%*.*^|findstr /b "[0-9][0-9][0-9][0-9]"') do call :Uprg %%i  
 
echo.
pause
goto :Ende
 
:Uprg
set Dateiname=%~1
set ZielOrdner=%Dateiname:~0,4%
echo Kopiere %Dateiname% nach %ZielOrdner%
copy %Quellordner%%Dateiname% %Quellordner%%Dateiname:~0,4%
:Ende
Endlocal

Das Problem welches sich mir nun stellt, er kann bisher nur nach den ersten vier Ziffern suchen, z.B. 2016 und legt dann einen Ordner 2016 an.
Wie setze ich nun für den Monat die ersten vier Ziffern auf beliebig und lasse ihn ab der fünften Ziffer nach dem Monat suchen?
Findstr bietet mir keine passende Parameter, zumindest habe ich die hier nicht gefunden:
https://technet.microsoft.com/en-us/library/bb490907.aspx
131301
131301 27.10.2016 aktualisiert um 12:24:50 Uhr
Goto Top
CLR C++
// SortFiles.cpp : main project file.
#include "stdafx.h" 

using namespace System;
using namespace System::IO;
using namespace System::Text::RegularExpressions;

int main(array<System::String ^> ^args)
{
	String^ sourceroot = "C:\\quelle";  
	String^ targetroot = "C:\\ziel";  

	array <String^> ^files = Directory::GetFiles(sourceroot,"*.*");  
	int cnt = 0;
	for each (String^ file in files){
		String^ filename = Path::GetFileName(file);
		Match^ m = (gcnew Regex("^(?i)(\\d{4})(\\d{2})(\\d{2})\\.(lgx|log)"))->Match(filename);  
		if (m->Success){
			String^ year = m->Groups[1]->Value;
			String^ month = m->Groups[2]->Value;
			String^ targetdir = targetroot + "\\" + year + "\\" + month;  

			if (!Directory::Exists(targetdir)){
				Directory::CreateDirectory(targetdir);
			}
			File::Move(file,targetdir + "\\" + filename);  
			Console::WriteLine("Moved file '" + file + "' to folder '" + targetdir + "'");  
			cnt++;
		}
	}
	Console::WriteLine("Fertig. " + cnt + " Datei(en) verschoben");  
	Console::WriteLine("\nTaste drücken zum beenden...");  
	Console::ReadLine();
    return 0;
}
rubberman
rubberman 27.10.2016 um 12:34:41 Uhr
Goto Top
Hallo Nils50122.

Visual Studio (C++)

Am liebsten wäre mir C++

mein ERSTES C Projekt
Was denn nun, C oder C++? Das sind 2 Sprachen, die kaum unterschiedlicher sein könnten.


mit einem einfachem Button

eine Oberfläche habe ich schon gebastelt
Dann ist es weder C, noch C++. Grafische Oberflächen gehören nicht zum Sprachstandard. Nicht mal die eigentliche Aufgabe deines Programms ließe sich ohne Verwendung der Windows API umsetzen. Keine Ahnung, was du da tust.


Wie setze ich nun für den Monat die ersten vier Ziffern auf beliebig und lasse ihn ab der fünften Ziffer nach dem Monat suchen?
Das hat nun überhaupt nichts mehr mit C oder C++ zu tun...
Die ersten 4 Ziffern beliebig, hast du ja schon. Du brauchst also an dein Suchpattern nur noch bspw. 10 für Oktober anzuhängen.

Grüße
rubberman
rubberman
rubberman 27.10.2016 um 12:37:58 Uhr
Goto Top
@131301

Sorry, aber dann doch lieber gleich C# als dieser unsägliche Mix face-wink

Grüße
rubberman
131301
131301 27.10.2016 aktualisiert um 12:44:15 Uhr
Goto Top
Klar würde ich auch machen, mit dem Mix hat er angefangen, dann kriegt er auch Mix weil er von Klicki-Bunti sprach dachte ich direkt an die CLR-Projects in VS face-smile

ATL/MFC/CLR and what the fuck....sonst noch, no one knows what he wants.
rubberman
rubberman 27.10.2016 um 12:46:31 Uhr
Goto Top
Naja, so lernt er weder C noch C++ noch C# und wenn er mal auf einen anderen Compiler wechselt ist Ebbe. Mit solchem Mist beschäftige ich mich gar nicht erst, schade um die Zeit face-wink

Grüße
rubberman
onlyforu8373
onlyforu8373 27.10.2016 um 12:56:18 Uhr
Goto Top
Jetzt mal ganz langsam.

Meinen Entwurf (die grafische Oberfläche) habe ich mit Visual Studio angelegt, vergesst meine ersten Worte mit C++.

Ich suche nun EINEN Code für Visual Studio der sich hinter dem Button "Sichern" verbirgt, nicht mehr nicht weniger face-smile
rubberman
rubberman 27.10.2016 um 13:00:22 Uhr
Goto Top
Du scheinst nicht zu wissen, wie viele Sprachen und Variationen Visual Studio unterstützt? Wenn du nicht mal erzählst, welche Art von Projekt du angelegt hast und auch nicht deinen bisherigen Code postest, ist dir nicht zu helfen.

Grüße
rubberman
131301
131301 27.10.2016 aktualisiert um 13:04:51 Uhr
Goto Top
Ich suche nun EINEN Code für Visual Studio der sich hinter dem Button "Sichern" verbirgt
Zum krumbiegen face-big-smile. Ich glaub du versuchst es erst mal mit VB.Net und C# für den Anfang deiner Programmiererkarriere ...
Beispielcode s. oben. und @rubberman
onlyforu8373
onlyforu8373 27.10.2016 um 13:04:40 Uhr
Goto Top
Windows Forms-Anwendung Visual C#.

Bisheriger Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Sicherungstool
{
    public partial class Form1 : Form
    {
        
       
        public Form1()
        {
           
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            
        }
    }
}
131301
131301 27.10.2016 um 13:05:19 Uhr
Goto Top
C#
c# nicht gleich C++ !!!!
onlyforu8373
onlyforu8373 27.10.2016 um 13:06:42 Uhr
Goto Top
Habs nun auch gesehen...
131301
131301 27.10.2016 aktualisiert um 13:07:36 Uhr
Goto Top
obigen Code kannst du mit da es die CLR verwendet genauso mit c# abbilden, da es die normalen NET Methoden verwendet. Einfach mal ansehen und nach c# konvertieren.
rubberman
rubberman 27.10.2016 um 13:09:29 Uhr
Goto Top
Das ist nichts weiter als zusammengeklickter Sch...
Hat jetzt schon 2 Buttons ohne aussagekräftigen Name. Glaub mir, so wird das nix. Lerne die Sprache.

Grüße
rubberman
(und raus)
onlyforu8373
onlyforu8373 02.11.2016 um 07:04:21 Uhr
Goto Top
So, habe mich nun ein bisschen durchgekämpft und siehe da es läuft.

Ein Problem bleibt mir allerdings noch:

Es wird File.Move genutzt, laut Recherche kann File.Move kein overwrite, deshalb kommt bei jeder Datei die schon vorhanden ist eine Messagebox hoch die bestätigt werden muss.

Habe schon versucht vorher eine Abfrage zu gestalten mit File.Exists und dann File.Delete.
Hat jedoch nicht so funktioniert wie ich es mir dachte. (An der falschen Stelle eingefügt?)

Perfekt wäre, wenn erkannt wird das eine Datei schon vorhanden -> dann kann der Bediener selber in einer Messagebox mit den Buttons Überschreiben oder behalten entscheiden ob diese Dateien kopiert werden sollen.

private void btnStart_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            int cnt = 0;
            foreach (string file in Directory.GetFiles(txtSource.Text, "*.*", SearchOption.TopDirectoryOnly))  
            {
                Match m = (new Regex(@"^(\d{4})(\d{2})(\d{2})\.(txt|log)$", RegexOptions.IgnoreCase)).Match(Path.GetFileName(file));  
                if (m.Success)
                {
                    try
                    {
                        string targetfolder = txtTarget.Text + "\\" + m.Groups[1].Value + "\\" + m.Groups[2].Value;  
                        if (!Directory.Exists(targetfolder)) { Directory.CreateDirectory(targetfolder); }
                       
                        File.Move(file, targetfolder + "\\" + Path.GetFileName(file));  
                        cnt++;
                    }
                    catch (Exception ex)
                    {
                        Cursor = Cursors.Default;
                        MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);  
                    }
                }
            }
            Cursor = Cursors.Default;
            MessageBox.Show("Vorgang abgeschlossen. " + cnt.ToString() + " Datei(en) verschoben.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);  
        }