Crear directorio del mes actual en BAT

Iniciado por ferrec, 15 Enero 2015, 16:43 PM

0 Miembros y 1 Visitante están viendo este tema.

elqueteconte

Saludos chicos de nuevo gracias por el apoyo y mil disculpas por la joda;

Les explico paso a paso:
1.- El usuario indica (en numeros) el mes. Es decir que hay que validar que solo coloque dos caracteres y que sean numeros entre 01 y 12.
2.- Verificar si la carpeta mes con el año está creada. Ejemplo: Si el usuario indica 09 entonces la carpeta sería Septiembre2015.
3.- Si la carpeta no existe;se crea la carpeta con el mes y el año, ejemplo Septiembre2015
4.- Buscar en el directorio donde se está ejecutando el bath todas las carpetas cuya estructura sea año, mes, dia corresponda al mes de la carpeta que acabo de crear y mover esas carpetas a la que acabo de crear. Ejemplo
Si cree la carpeta miruta/Septiembre2015 y en miruta/ hay carpetas 20150901, 20150902 ... hasta 20150930 y moverla a  miruta/Septiembre2015
YA TODO ESTO ESTA
5.- Luego de haber movido las carpetas al direcotorio el script entra en la carpeta del día 1 y copia la información sobre otro archivo y sí susesivamente hasta el ultimo día. Esto hará que al final el archivo resultante tendra la información de todos los días.
Yo supongo que el script entra en un for desde el primer día hasta el ultimo y dentro del for estaría la sentencia de comiando.
Sería algo así:
Para dia=1 hasta dia=31
copiar en archivoA plantilla la información del archivoA
copiar en archivoB plantilla la información del archivoB
Fin para

6.- Buscar caracter especial en los archivos CM.txt; GL.txt; IMP6000.txt;IMP6001.txt; IMP6002.txt y IMP6003.txt y eliminarlo.

7.- Cerrar archivos.

Me da pena con ustedes mi pana; pero la programación no es mi fuerte; trabajo en el área de tecgonologia a nivel de administración de recursos pero he adquirido una nueva responsabilidad y pues me toca tirar codigo, pero este script es urgente que lo haga.

Sin mas;

elqueteconte

elqueteconte

Cita de: Eleкtro en 13 Octubre 2015, 18:19 PM
Eso lo puedes solucionar realizando una copia en modo binario:

De todas formas, permíteme una pregunta... si puedes manejarte con VB.Net o con VBS, ¿por qué utilizas Batch?, al menos para merger o fusionar archivos, con lo fácil y "limpio" que es en los lenguajes mencionados no tendrias problemas de ese tipo.

Saludos!


Saludos Alektro;

Gracias oir tu tiempo.

Yo manejo .bath pues cuando comencé con el proceso de integración, uno de los pasos era el usar este script el cual tenía que editar cada vez que hubiesen mas días por agregar, es por ello que vez en el script como se repite el mismo comando y solo cambia el día, claro cada vez que agregas un día el comando copy se repite 6 veces.

De nuevo quiero expresarte mi agradecimiento por el apoyo.

Ya estoy bajando el Visual Studio Express para ver y estudiar el código.

Sin mas,

elqueteconte

elqueteconte

#22
Cita de: Eleкtro en 13 Octubre 2015, 18:19 PM
Eso lo puedes solucionar realizando una copia en modo binario:

De todas formas, permíteme una pregunta... si puedes manejarte con VB.Net o con VBS, ¿por qué utilizas Batch?, al menos para merger o fusionar archivos, con lo fácil y "limpio" que es en los lenguajes mencionados no tendrias problemas de ese tipo.

Saludos!

Estoy investigando de como leer las carpetas que se movieron y luego copiar su contenido.
Inicialmente tendría que entrar en carpeta por carpeta para copiar los archivos, claro como el número de carpetas puede variar entonces tendría que manejarlo con un for y luego que entre en cada carpeta hacer el copy la función sería mas o menos así:

Código (vbnet) [Seleccionar]

Private Sub UnirTxt()
       ' Declaro las variables de los archivos TXT
       Dim CM As String() = Directory.GetFiles(dateDir, "CM.txt")
       Dim GL As String() = Directory.GetFiles(dateDir, "GL.txt")
       Dim IMP60 As String() = Directory.GetFiles(dateDir, "IMP6000.txt")
       Dim IMP61 As String() = Directory.GetFiles(dateDir, "IMP6001.txt")
       Dim IMP62 As String() = Directory.GetFiles(dateDir, "IMP6002.txt")
       Dim IMP63 As String() = Directory.GetFiles(dateDir, "IMP6003.txt")

       ' Declaro las carpetas que estan dentro de la carpeta creada
       Dim Folders As New DirectoryInfo(dateDir)

       'Verifico si existen los archivos, en caso de existir los elimino.
       If File.Exists(CM(0)) Then File.Delete(CM(0))
       If File.Exists(GL(0)) Then File.Delete(GL(0))
       If File.Exists(IMP61(0)) Then File.Delete(IMP61(0))
       If File.Exists(IMP62(0)) Then File.Delete(IMP62(0))
       If File.Exists(IMP63(0)) Then File.Delete(IMP63(0))

       Dim swcm As New StreamWriter(CM(0))
       Dim swgl As New StreamWriter(GL(0))
       Dim swi60 As New StreamWriter(IMP60(0))
       Dim swi61 As New StreamWriter(IMP61(0))
       Dim swi62 As New StreamWriter(IMP62(0))
       Dim swi63 As New StreamWriter(IMP63(0))

       'Entro en cada carpeta día
       For Each Folder As DirectoryInfo In Folders.GetDirectories
           ' Tomo el nombre del archivo y hago la copia
           For Each txtfile As FileInfo In Folder.GetFiles
               If Mid(txtfile.Name, 1, 2) = "CM" Then
                   swcm.Write(File.ReadAllText(txtfile.FullName))
               End If
               If Mid(txtfile.Name, 1, 2) = "GL" Then
                   swgl.Write(File.ReadAllText(txtfile.FullName))
               End If
               If Mid(txtfile.Name, 6, 7) = "01" Then
                   swi60.Write(File.ReadAllText(txtfile.FullName))
               End If
               If Mid(txtfile.Name, 6, 7) = "02" Then
                   swi62.Write(File.ReadAllText(txtfile.FullName))
               End If
               If Mid(txtfile.Name, 6, 7) = "03" Then
                   swi63.Write(File.ReadAllText(txtfile.FullName))
               End If
           Next
       Next
       swcm.Close()
       swgl.Close()
       swi60.Close()
       swi61.Close()
       swi62.Close()
       swi63.Close()
End Sub


Que opinas?

Como lo integro con tu código?

Gracias mil de nuevo.

Eleкtro

#23
¿Y esto lleva aquí desde el 13 de octubre? xD lo siento por la tardanza, luego le doy un repaso y te comento.

saludos




EDITO:

Prueba de la siguiente manera, pero no se muy bien como tienes la estructura de carpetas y archivos así que tal vez tengas que cambiar los parámetros de la iteración de carpetas y/o archivos.

Lo he escrito al vuelo sin testearlo (es un coñazo volver a recrear la estructura de archivos y carpetas). De todas formas creo que este ejemplo te servirá para que lo consigas hacer por ti mismo.

Código (vbnet) [Seleccionar]
   Public Sub FindAndMergeFiles(ByVal sourceDir As String)

       Const NameCM As String = "CM"
       Const NameGL As String = "GL"
       Const NameImp60 As String = "IMP6000"
       Const NameImp61 As String = "IMP6001"
       Const NameImp62 As String = "IMP6002"
       Const NameImp63 As String = "IMP6003"

       Dim curFilename As String

       ' Itero cada directorio del directorio de origen.
       For Each topDir As DirectoryInfo In New DirectoryInfo(sourceDir).
                                               GetDirectories("*", SearchOption.TopDirectoryOnly)

           ' Itero de forma recursiva cada subdirectorio del directorio actual.
           For Each subDir As DirectoryInfo In topDir.GetDirectories("*", SearchOption.AllDirectories)

               ' Itero de forma recursiva cada archivo de texto del directorio actual.
               For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.AllDirectories)

                   If txtfile.Name.Equals(NameCM, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameCM

                   ElseIf txtfile.Name.Equals(NameGL, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameGL

                   ElseIf txtfile.Name.Equals(NameImp60, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameImp60

                   ElseIf txtfile.Name.Equals(NameImp61, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameImp61

                   ElseIf txtfile.Name.Equals(NameImp62, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameImp62

                   ElseIf txtfile.Name.Equals(NameImp63, StringComparison.OrdinalIgnoreCase) Then
                       curFilename = NameImp63

                   Else
                       curFilename = String.Empty

                   End If

                   If Not String.IsNullOrEmpty(curFilename) Then

                       Debug.WriteLine(topDir.FullName)
                       Debug.WriteLine(subDir.FullName)
                       Debug.WriteLine(txtfile.FullName)
                       Debug.WriteLine(Path.Combine(topDir.FullName, curFilename))

                       Using sr As StreamReader = txtfile.OpenText
                           File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)
                       End Using

                   End If

               Next txtfile

           Next subDir

       Next topDir

   End Sub


Modo de empleo en el código fuente que compartí en la página anterior:
Código (vbnet,5,6) [Seleccionar]
...
' Muevo los directorios (si alguno) con formato de fecha específico (ej. "yyyyMMdd"), del directorio fuente, al directorio de destino.
DateDirUtil.MoveDateDirectories(Me.year, monthNumber, DateDirUtil.DirNameFormat, Me.fdg.SelectedPath, dateDir)

' Merge text files.
DateDirUtil.FindAndMergeFiles(Me.fdg.SelectedPath)
...








elqueteconte

Dale mi pana.

Gracias mil de nuevo....


elqueteconte

#25
Saludos mi pana,

Estoy testeando la función y al principio me estaba dando error pues no hacía el merge de los archivos, entraba en cada carpeta, leia los archivos pero no entraba aqui:

If Not String.IsNullOrEmpty(curFilename) Then

                       Debug.WriteLine(topDir.FullName)
                       Debug.WriteLine(subDir.FullName)
                       Debug.WriteLine(txtfile.FullName)
                       Debug.WriteLine(Path.Combine(topDir.FullName, curFilename))

                       Using sr As StreamReader = txtfile.OpenText
                           File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)
                       End Using

                   End If


El problema era que cuando hacía la comparación de los nombres de los archivos con las constantes:

If txtfile.Name.Equals(NameCM, StringComparison.OrdinalIgnoreCase) Then
                        curFilename = NameCM


La comparación no se daba pues el nombre del archivo es CM.TXT y no CM como estaba definido en las contantes; así que modifiqué esa porción del codigo y voilà funcona la función reune todos los archivos en uno solo.

Así quedó la porción final

        Const NameCM As String = "CM.TXT"
        Const NameGL As String = "GL.TXT"
        Const NameImp60 As String = "IMP6000.TXT"
        Const NameImp61 As String = "IMP6001.TXT"
        Const NameImp62 As String = "IMP6002.TXT"
        Const NameImp63 As String = "IMP6003.TXT"


Pero ahora me está dando este error:
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'C:\Users\liderapp\Documents\Scripts\Octubre2015\CM.TXT' because it is being used by another process.
Eso sucede justo aqui:

File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)


Cuando ya ha hecho el barrido de todas las carpetas.

Se debe a que el archivo ya está abierto y entonces al intentar abrirlo de nuevo da el error?

Gracias mil por el apoyo mi pana.

elqueteconte

Cita de: elqueteconte en 19 Octubre 2015, 16:33 PM
Saludos mi pana,

Estoy testeando la función y al principio me estaba dando error pues no hacía el merge de los archivos, entraba en cada carpeta, leia los archivos pero no entraba aqui:

If Not String.IsNullOrEmpty(curFilename) Then

                       Debug.WriteLine(topDir.FullName)
                       Debug.WriteLine(subDir.FullName)
                       Debug.WriteLine(txtfile.FullName)
                       Debug.WriteLine(Path.Combine(topDir.FullName, curFilename))

                       Using sr As StreamReader = txtfile.OpenText
                           File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)
                       End Using

                   End If


El problema era que cuando hacía la comparación de los nombres de los archivos con las constantes:

If txtfile.Name.Equals(NameCM, StringComparison.OrdinalIgnoreCase) Then
                        curFilename = NameCM


La comparación no se daba pues el nombre del archivo es CM.TXT y no CM como estaba definido en las contantes; así que modifiqué esa porción del codigo y voilà funcona la función reune todos los archivos en uno solo.

Así quedó la porción final

        Const NameCM As String = "CM.TXT"
        Const NameGL As String = "GL.TXT"
        Const NameImp60 As String = "IMP6000.TXT"
        Const NameImp61 As String = "IMP6001.TXT"
        Const NameImp62 As String = "IMP6002.TXT"
        Const NameImp63 As String = "IMP6003.TXT"


Pero ahora me está dando este error:
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'C:\Users\liderapp\Documents\Scripts\Octubre2015\CM.TXT' because it is being used by another process.
Eso sucede justo aqui:

File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)


Cuando ya ha hecho el barrido de todas las carpetas.

Se debe a que el archivo ya está abierto y entonces al intentar abrirlo de nuevo da el error?

Gracias mil por el apoyo mi pana.

Investigando un poco en la nube; me sugieren que use este comando:


                Using loFileStream As System.IO.FileStream = New FileStream(lcFile, FileMode.Create)
                    loStreamWriter = New StreamWriter(loFileStream, cEncoding)
                    loStreamWriter.Write(cString)
                    loStreamWriter.Close()
                End Using


Q opinas al respecto?
Como lo adapto a nuestro script?

Sin mas,

Tu pana agradecido... jejejejejeje

Eleкtro

#27
Cita de: elqueteconte en 19 Octubre 2015, 16:33 PMme está dando este error:
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'C:\Users\liderapp\Documents\Scripts\Octubre2015\CM.TXT' because it is being used by another process.
Eso sucede justo aqui:

File.AppendAllText(Path.Combine(topDir.FullName, curFilename), sr.ReadToEnd, Encoding.Default)


Cuando ya ha hecho el barrido de todas las carpetas.

Cita de: elqueteconte en 19 Octubre 2015, 16:33 PMSe debe a que el archivo ya está abierto y entonces al intentar abrirlo de nuevo da el error?

Exactamente se debe a eso que has deducido. El archivo "...\topdir\xxx.txt" se procesa de forma inesperada en la iteración, es decir, se abre el archivo en modo lectura pero se intentan guardar/adjuntar datos en modo escritura. Esto sucede por que como escribí el código al vuelo cometí un pequeño fallo en esta linea:
Citar
Código (vbnet) [Seleccionar]
...
For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.AllDirectories)
...

Modifica topDir por subDir

Lo siento por ese pequeño descuido. Con esa amodificación ya debería funcionarte como es esperado.




Cita de: elqueteconte en 21 Octubre 2015, 14:09 PM
Investigando un poco en la nube; me sugieren que use este comando:


               Using loFileStream As System.IO.FileStream = New FileStream(lcFile, FileMode.Create)
                   loStreamWriter = New StreamWriter(loFileStream, cEncoding)
                   loStreamWriter.Write(cString)
                   loStreamWriter.Close()
               End Using


Q opinas al respecto?
Como lo adapto a nuestro script?

Una vez hayas corregido el fallo que comenté entonces no hay necesidad de hacer nada más. Aparte, en el código que has mostrado lo apropiado sería manejar la accesibilidad de un objeto StreamWriter para manipular texto, ya que un FileStream se utiliza más bien para escribir secuencias de bytes (y entonces tendrías que obtener los bytes del texto que quieres añadir), es completamente innecesario un FileStream en este escenario, además, le estás pasando el flag FileMode.Create el cual sobreescribirá el archivo en cada iteración que hagas, en lugar de adjuntar texto al archivo que ya estaba creado.

De todas formas te muestro como sería la adaptación de un FileStream, pero como ya digo es completamente innecesario:
Código (vbnet) [Seleccionar]
...
Dim enc As Encoding = Encoding.Default
Dim byteData As Byte()

Using sr As StreamReader = txtfile.OpenText

   Using fs As New FileStream(Path.Combine(topDir.FullName, curFilename),
                              FileMode.Append, FileAccess.Write, FileShare.None, 128)

       byteData = enc.GetBytes(sr.ReadToEnd & Environment.NewLine)
       fs.Write(byteData, 0, byteData.Length)

   End Using ' fs

End Using ' sr
...





Prueba el siguiente código. Lo he refactorizado bastante.

Código (vbnet) [Seleccionar]
Public Sub MergeFiles(ByVal sourceDir As String)

   Dim fileNames As String() =
       {
           "CM.txt", "GL.txt",
           "IMP6000.txt", "IMP6001.txt", "IMP6002.txt", "IMP6003.txt"
       }

   Dim curFilename As String = String.Empty

   For Each topDir As DirectoryInfo In New DirectoryInfo(sourceDir).GetDirectories("*", SearchOption.TopDirectoryOnly)

       ' Elimino los archivos principales ("...\topDir\CM.txt", "...\topDir\GL.txt", etc...) de sesiones anteriores.
       For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.TopDirectoryOnly)
           If fileNames.Contains(txtfile.Name, StringComparer.OrdinalIgnoreCase) Then
               txtfile.Delete()
           End If
       Next txtfile

       For Each subDir As DirectoryInfo In topDir.GetDirectories("*", SearchOption.AllDirectories)

           For Each txtfile As FileInfo In subDir.GetFiles("*.txt", SearchOption.AllDirectories)

               If fileNames.Contains(txtfile.Name, StringComparer.OrdinalIgnoreCase) Then

                   curFilename = fileNames.First(Function(filename) filename.Equals(txtfile.Name, StringComparison.OrdinalIgnoreCase))

                   Using sr As StreamReader = txtfile.OpenText

                       Using sw As New StreamWriter(Path.Combine(topDir.FullName, curFilename), append:=True, encoding:=Encoding.Default, bufferSize:=128)
                           sw.WriteLine(sr.ReadToEnd)
                       End Using ' sw

                   End Using ' sr

               End If

           Next txtfile

       Next subDir

   Next topDir

End Sub


NOTA: SI TE SURGEN MÁS DUDAS SOBRE VB.NET POR FAVOR CREA UN POST EN LA SECCIÓN DEDICADA A LA PLATAFORMA .NET
http://foro.elhacker.net/net-b62.0/

Saludos








elqueteconte

Liiiisto...!

Hermano eres un duro en .net te felicito....

Mil gracias; ahora me toca ir a otra fase de este proyecto esto es apenas el comienzo, espero poder seguir con tu apoyo.

Dale creare los hilos en el foro que corresponde.

Gracias mil de nuevo mi pana.

Un abrazo y feliz fín de semana.


Eleкtro

Hola

- Está prohibido revivir temas antiguos.
- Es obligatorio formatear un bloque de código, ¡esto es un foro de programación!

Sigue las normas, por favor.

Tema Cerrado

Saludos