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.

Mad Antrax

Cita de: elqueteconte en  9 Octubre 2015, 17:17 PM
Me haz dejado loco jajajajaja.

Gracias mil.

Pensé en hacerlo en VB.net.

Voy a darle por allí a ver que logro.

Te podré contactar por este hilo o abro uno nuevo?

Utiliza éste

Mi codigo es VBS, copia y pega todo el codigo en un "bloc de notas" (notepad) y guarda el contenido con el nombre que desees, pero asegúrate de guardarlo con la extensión .vbs al final. Le das doble-click y lo pruebas.

Verás que he implementado las opciones 1, 2 y 3. Falta la 4 que es un poco más compleja. Necesitarás saber el formato de nombres EXACTO que se utiliza en las carpetas existentes, hacer un Mid() para leer la posición del mes en el nombre, comparar y luego llamar a la función CopyFolder o MoveFolder del objeto oFSO

Si tienes dudas pregunta por aquí mismo
No hago hacks/cheats para juegos Online.
Tampoco ayudo a nadie a realizar hacks/cheats para juegos Online.

elqueteconte

Saludos Mad;

Gracias mil de nuevo, me puse a investigar y encontré el vbsedit que es un editor para vbs y funciona al pelo.

Te confieso que no soy programador nato así que me estoy rompiendo el coco para ver como logro llevar el concepto al código.

Pues estoy claro en lo que necesito pero no se como aplicarlo, googleando encontré este script:


Dim fso, folder, subFlds, fld, s
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(path)
Set subFlds = folder.SubFolders
s = ""
For Each fld in subFlds
   s = s & fld.name
   s = s & "<br />"
Next
ShowFolderList = s


Pero cuando se ejecuta la instrucción Set folder = fso.GetFolder(path) me da error de Acceso Denegado.

Teoricamente este me lista las carpetas que estan al mismo nivel de donde se está ejecutando el script, luego de esto debo mover las carpetas hacia la carpeta creada. El asunto es que las carpetas a mover deben corresponder al mes de la carpeta que se creo.

De pana que mil gracias por la ayuda hermano...

Mad Antrax

Te veo perdido jejeje, pero al menos veo que te has buscado las castañas y no vas mal encaminado.

Estoy en una partida de league of legends, dame 30 minutos y te respondo con el codigo correcto
No hago hacks/cheats para juegos Online.
Tampoco ayudo a nadie a realizar hacks/cheats para juegos Online.

elqueteconte

Perdido no perdidisimo jajajajajaja.

Se lo necesito, lo que no se es como hacerlo....

Gracias pana....

Mad Antrax

Cita de: elqueteconte en  9 Octubre 2015, 17:17 PM
Me haz dejado loco jajajajaja.

Gracias mil.

Pensé en hacerlo en VB.net.

Voy a darle por allí a ver que logro.

Te podré contactar por este hilo o abro uno nuevo?

Aquí lo tienes

Código (vb) [Seleccionar]
Set oFSO = CreateObject("Scripting.FileSystemObject")

iMes = InputBox("Introduce el mes: ")

If isNumeric(iMes) = False Then
While isNumeric(iMes) = False
MsgBox "Solo se permiten valores numéricos", vbExclamation + vbOkOnly
iMes = InputBox("Introduce el mes: ")
Wend
End If

If iMes < 1 Or iMes > 12 Then
While iMes < 1 Or iMes > 12
MsgBox "Solo se permiten valores numéricos entre 1 y 12", vbExclamation + vbOkOnly
iMes = InputBox("Introduce el mes: ")
Wend
End If

Select Case iMes
Case 1
sMes = "Enero"
Case 2
sMes = "Febrero"
Case 3
sMes = "Marzo"
Case 4
sMes = "Abril"
Case 5
sMes = "Mayo"
Case 6
sMes = "Junio"
Case 7
sMes = "Julio"
Case 8
sMes = "Agosto"
Case 9
sMes = "Septiembre"
Case 10
sMes = "Octubre"
Case 11
sMes = "Noviembre"
Case 12
sMes = "Diciembre"
End Select

sFolder = sMes & Year(Now)

If oFSO.FolderExists(sFolder) = True Then
MsgBox "La carpeta " & sFolder & " ya existe", vbInformation + vbOkOnly
Else
MsgBox "La carpeta " & sFolder & " no existe", vbInformation + vbOkOnly
oFSO.CreateFolder(sFolder)
End If

Parent = oFSO.GetParentFolderName(WScript.ScriptFullName)

Set Folder = oFSO.GetFolder(Parent)
Set SubFolder = Folder.SubFolders
For Each SubFolders in SubFolder
If isNumeric(SubFolders.Name) = True Then
If Len(SubFolders.Name) = 8 Then
If CInt(Mid(SubFolders.Name, 5, 2)) = CInt(iMes) Then
Call oFSO.MoveFolder(Parent & "\" & SubFolders.Name, Parent & "\" & sFolder & "\" & SubFolders.Name)
End If
End If
End If
Next
msgbox "Script finalizado"


Funciona si la estructura de carpetas es "AÑO MES DIA", por ejemplo:

20150327

El Script, después de introducir 3 (marzo) te moverá las carpetas cuyo nombre sea xxxx03xx dentro de Marzo2015

Lee las líneas, se entienden solas.
No hago hacks/cheats para juegos Online.
Tampoco ayudo a nadie a realizar hacks/cheats para juegos Online.

Eleкtro

#15
Cita de: elqueteconte en  9 Octubre 2015, 17:17 PMPensé en hacerlo en VB.net.

El código del compañero @Mad Antrax está muy pero que muy bien, sin embargo, al escucharte decir eso me han entrado ganas de mostrarte un ejemplo alternativo e iguálmente funcional en dicho lenguaje, ya que igual que tengo bien sabido que @Mad Antrax ama VBS, yo amo Vb.Net :P. Si lo hicieras en .Net (VB.Net o C#) la eficacia general del código aumentaria considerablemente en comparación con un lenguaje de scripting limitado (sobre todo si hablamos de Batch), aunque en realidad, con VBS tienes más que suficiente para llevar a cabo esa tarea.

Aquí tienes el archivo de la solución de Visual Studio 2013, como ya he mencionado cumple todas las funciones que has pedido, eso sí, lo que quieras añadir o modificar ya es cosa tuya. Si tienes preguntas sobre este lenguaje por favor hazlas en el subforo correspondiente, no desviemos más el tema aquí.



http://www.mediafire.com/download/4qoklj8s64jwuvv/WindowsApplication6.rar


Y aquí te muestro parte del código fuente. El resto del código que no muestro aquí simplemente es el código generado automaticamente por VS, el código de la UI.

Por mencionar algo de este código que te puede interesar rehutilizable para el futuro, en la función GetMonthName utilizo un objeto de globalización , CultureInfo, del cual obtengo de forma administrada los nombres de los meses en la cultura específica, en este caso "es-ES".

Te lo he dejado todo con varios comentarios para que te ayuden a comprender lo que hago.

MainForm.vb
Código (vbnet) [Seleccionar]
Imports System
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms

Public NotInheritable Class MainForm : Inherits Form

   Private year As Integer = DateTime.Today.Year ' O... '2015'
   Private sourceDir As String = Directory.GetCurrentDirectory() ' O... ".\"

   Public Sub New()

       Me.InitializeComponent()

       With Me.DTPMonth ' Personalizo el formato de entrada del DateTimePicker.
           .CustomFormat = "MM" ' 01-12
           .Format = DateTimePickerFormat.Custom
           .Value = DateTime.Today
       End With

   End Sub

   Private Sub BtAccept_Click(ByVal sender As Object, ByVal e As EventArgs) _
   Handles BtAccept.Click

       ' Obtengo la ruta absoluta del directorio con fecha. (ej. "C:\Ruta\Octubre2015")
       Dim monthNumber As Integer = Me.DTPMonth.Value.Month
       Dim dateDir As String = DateUtil.GetDateDirPath("es-ES", Me.sourceDir, Me.year, monthNumber)

       ' Creo el directorio con fecha (si no existe).
       DateUtil.CreateDirectory(dateDir)

       ' Muevo los directorios (si alguno) con formato de fecha específico (ej. "yyyyMMdd"), del directorio fuente, al directorio de destino.
       DateUtil.MoveDateDirectories(Me.year, monthNumber, DateUtil.DirNameFormat, sourceDir, dateDir)

   End Sub

   Private Sub BtCancel_Click(ByVal sender As Object, ByVal e As EventArgs) _
   Handles BtCancel.Click

       ' Cierro este form, y con él termina la ejecución de la aplicación.
       Me.Close()

   End Sub

End Class


+

DateUtil.vb
Código (vbnet) [Seleccionar]
Imports System
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Security.AccessControl
Imports System.Security.Principal

Public Module DateUtil

   ''' <summary>
   ''' El formato por defecto del nombre de directorio. ("yyyyMMdd" equivale a "AñoMesDia").
   ''' </summary>
   ''' <remarks>
   ''' El formato se puede cambiar, pero respetando los especificadores actuales, que son "yyyy", "MM" y "dd", los cuales son intercambiables entre si.
   ''' Para usar otros especificadores haría falta una refactorización del código (el método <see cref="MoveDateDirectories"/>) para implementar su soporte.
   ''' Los especificadores disponibles se pueden encontrar en la documentación online de MSDN:
   ''' https://msdn.microsoft.com/en-us/library/8kb3ddd4%28v=vs.110%29.aspx
   ''' </remarks>
   Public Const DirNameFormat As String = "yyyyMMdd" ' ej. "20150131"

   ''' <summary>
   ''' Devuelve el nombre de un mes del año, en el lenguaje específicado.
   ''' </summary>
   Public Function GetMonthName(ByVal cultureName As String,
                                ByVal month As Integer) As String

       If (month < 1I) OrElse (month > 12I) Then
           Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")

       ElseIf Not (From ci As CultureInfo In CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures)
                   Where ci.Name.Equals(cultureName, StringComparison.OrdinalIgnoreCase)).Any Then
           Throw New NotImplementedException(message:=String.Format("Culture '{0}' not recognized, maybe name is wrong typed or culture is not installed.", cultureName))

       Else
           Dim ci As CultureInfo = CultureInfo.GetCultureInfo(cultureName)
           Return ci.TextInfo.ToTitleCase(ci.DateTimeFormat.MonthNames(month - 1))

       End If

   End Function

   ''' <summary>
   ''' Devuelve la ruta absoluta del directorio de destino con el nombre de la fecha, en el lenguaje específicado.
   ''' ej. "C:\Ruta\Octubre2015"
   ''' </summary>
   Public Function GetDateDirPath(ByVal cultureName As String,
                                  ByVal targetDir As String,
                                  ByVal year As Integer,
                                  ByVal month As Integer) As String

       If (CStr(year).Length <> 4I) Then
           Throw New ArgumentOutOfRangeException(paramName:="year", message:="A value of 4 digits' is required.")

       ElseIf (month < 1I) OrElse (month > 12I) Then
           Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")

       Else
           Return Path.Combine(targetDir, String.Format("{0}{1}", DateUtil.GetMonthName(cultureName, month), year))

       End If

   End Function

   ''' <summary>
   ''' Crea un directorio en el directorio especificado.
   ''' </summary>
   Public Sub CreateDirectory(ByVal targetDir As String)

       ' Le asigno permisos de usuario personalizados a la carpeta existente o la carpeta que se creará.

       Dim userId As SecurityIdentifier = WindowsIdentity.GetCurrent.User
       Dim dirSec As New DirectorySecurity
       With dirSec
           .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.CreateDirectories, AccessControlType.Allow))
           .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.CreateFiles, AccessControlType.Allow))
           .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.ListDirectory, AccessControlType.Allow))
           .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.ReadAndExecute, AccessControlType.Allow))
           .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.Write, AccessControlType.Allow))
           ' .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.FullControl, AccessControlType.Allow))
       End With

       If Directory.Exists(targetDir) Then
           Directory.SetAccessControl(targetDir, dirSec)
       Else
           Directory.CreateDirectory(targetDir, directorySecurity:=dirSec)
       End If

   End Sub

   ''' <summary>
   ''' Mueve los directorios cuyo nombre contenga un formato de fecha especifico (intercambiable entre "yyyy", "MM", y "dd") al directorio de destino especificado.
   ''' </summary>
   Public Sub MoveDateDirectories(ByVal year As Integer,
                                  ByVal month As Integer,
                                  ByVal dateFormat As String,
                                  ByVal sourceDir As String,
                                  ByVal targetDir As String)

       If (CStr(year).Length <> 4I) Then
           Throw New ArgumentOutOfRangeException(paramName:="year", message:="A value of 4 digits' is required.")

       ElseIf (month < 1I) OrElse (month > 12I) Then
           Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")

       ElseIf (dateFormat.Replace("y", "").Replace("M", "").Replace("d", "").Length <> 0) Then
           Throw New NotImplementedException(message:="Specified date format is not implemented, only 'yyyy', 'MM' and 'dd' are interchangeable.")

       ElseIf Not Directory.Exists(sourceDir) Then
           Throw New DirectoryNotFoundException(message:=String.Format("Source directory not found: '{0}'", sourceDir))

       ElseIf Not Directory.Exists(targetDir) Then
           Throw New DirectoryNotFoundException(message:=String.Format("Target directory not found: '{0}'", targetDir))

       Else
           Dim sourceDirInfo As New DirectoryInfo(sourceDir)
           Dim targetDirInfo As New DirectoryInfo(targetDir)

           ' Obtengo una colección con los nombres de directorio con el formato de fecha especificado. (ej. de Octubre 2015:  20151001 ... 20151031)
           Dim dateDirNames As IEnumerable(Of String) =
               From day As Integer In Enumerable.Range(1, DateTime.DaysInMonth(year, month))
               Select dateFormat.Replace("yyyy", CStr(year)).
                                 Replace("MM", CStr(month).PadLeft(2, "0"c)).
                                 Replace("dd", CStr(day).PadLeft(2, "0"c))

           ' Obtengo una colección con las rutas absolutas de los directorios que cumplen las condiciones de formato de fecha.
           Dim directories As IEnumerable(Of DirectoryInfo) =
               From dirInfo As DirectoryInfo In sourceDirInfo.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
               Where dateDirNames.Contains(dirInfo.Name)

           ' Un simple mensaje de información o aviso cuando no se encuentra ningún directorio el cual mover.
           If (Not directories.Any) Then
               Dim msg As String = String.Format("No ha sido encontrado ningún directorio en '{0}' que cumpla las condiciones de formato de fecha.", sourceDirInfo.FullName)
               MessageBox.Show(msg, "By Elektro", MessageBoxButtons.OK, MessageBoxIcon.Information)

           Else
               ' Por último, muevo los directorios que cumplieron las condiciones de formato de fecha.
               For Each dirInfo As DirectoryInfo In directories

                   Debug.WriteLine(String.Format("Moviendo: {0}", dirInfo.FullName))

                   Try
                       dirInfo.MoveTo(Path.Combine(targetDirInfo.FullName, dirInfo.Name))

                   Catch ex As Exception
#If DEBUG Then
                       Throw ex
#Else
                       MessageBox.Show(ex.Message & Environment.NewLine & ex.StackTrace, "By Elektro", MessageBoxButtons.OK, MessageBoxIcon.Error)
#End If

                   End Try

               Next dirInfo

           End If ' Not directories.Any

       End If ' dateFormat...

   End Sub

End Module


Que lo apreveches.

Saludos!








Mad Antrax

jajaj, te saliste Eleкtro ;-)

Sí, yo adoro VBS, hoy en día es el único lenguaje que utilizo de forma profesional en el trabajo y la verdad me permite resolver todos los problemas y necesidades que se me plantean en el trabajo. Tu script en .net es awesome y mas elaborado con el control de errores y permisos, en definitiva; una pasada de codigo.

Un saludo jefe ;D
No hago hacks/cheats para juegos Online.
Tampoco ayudo a nadie a realizar hacks/cheats para juegos Online.

elqueteconte

 ;-) ;-) ;-) ;-) ;-)

Son lo maximo chicos....

Mil gracias, yo tengo un libro de VB.Net me voy a poner a aprender pues este proceso no terminar aquí; hasta ahora han trabajado en el entorno lo que viene es la fusión de los archivos txt que están en cada carpeta.

Miren este archivo .bat

copy /y blancos\*.TXT .

copy CM.txt + C:\carp1\Emp1\20150908\CM.txt CM.txt
copy GL.txt + C:\carp1\Emp1\20150908\GL.txt GL.txt
copy IMP6000.txt + C:\carp1\Emp1\20150908\IMP6000.txt IMP6000.txt
copy IMP6001.txt + C:\carp1\Emp1\20150908\IMP6001.txt IMP6001.txt
copy IMP6002.txt + C:\carp1\Emp1\20150908\IMP6002.txt IMP6002.txt
copy IMP6003.txt + C:\carp1\Emp1\20150908\IMP6003.txt IMP6003.txt

copy CM.txt + C:\carp1\Emp1\20150909\CM.txt CM.txt
copy GL.txt + C:\carp1\Emp1\20150909\GL.txt GL.txt
copy IMP6000.txt + C:\carp1\Emp1\20150909\IMP6000.txt IMP6000.txt
copy IMP6001.txt + C:\carp1\Emp1\20150909\IMP6001.txt IMP6001.txt
copy IMP6002.txt + C:\carp1\Emp1\20150909\IMP6002.txt IMP6002.txt
copy IMP6003.txt + C:\carp1\Emp1\20150909\IMP6003.txt IMP6003.txt

copy CM.txt + C:\carp1\Emp1\20150910\CM.txt CM.txt
copy GL.txt + C:\carp1\Emp1\20150910\GL.txt GL.txt
copy IMP6000.txt + C:\carp1\Emp1\20150910\IMP6000.txt IMP6000.txt
copy IMP6001.txt + C:\carp1\Emp1\20150910\IMP6001.txt IMP6001.txt
copy IMP6002.txt + C:\carp1\Emp1\20150910\IMP6002.txt IMP6002.txt
copy IMP6003.txt + C:\carp1\Emp1\20150910\IMP6003.txt IMP6003.txt

copy CM.txt + C:\carp1\Emp1\20150911\CM.txt CM.txt
copy GL.txt + C:\carp1\Emp1\20150911\GL.txt GL.txt
copy IMP6000.txt + C:\carp1\Emp1\20150911\IMP6000.txt IMP6000.txt
copy IMP6001.txt + C:\carp1\Emp1\20150911\IMP6001.txt IMP6001.txt
copy IMP6002.txt + C:\carp1\Emp1\20150911\IMP6002.txt IMP6002.txt
copy IMP6003.txt + C:\carp1\Emp1\20150911\IMP6003.txt IMP6003.txt

copy CM.txt + C:\carp1\Emp1\20150912\CM.txt CM.txt
copy GL.txt + C:\carp1\Emp1\20150912\GL.txt GL.txt
copy IMP6000.txt + C:\carp1\Emp1\20150912\IMP6000.txt IMP6000.txt
copy IMP6001.txt + C:\carp1\Emp1\20150912\IMP6001.txt IMP6001.txt
copy IMP6002.txt + C:\carp1\Emp1\20150912\IMP6002.txt IMP6002.txt
copy IMP6003.txt + C:\carp1\Emp1\20150912\IMP6003.txt IMP6003.txt

Fijense que el .bat hace un recorrido por cada carpeta y copia los archivos que estén en esta dentro de otr archivo con el mismo nombre que se encuentra en el nivel superior, es decir, si la carpeta ppal se llama Octubre2015 el proceso hace un recorrido por las carpetas desde la 20151001 hasta 2015610N (donde N es el último día del mes) y crea los archivos a fusionados.

El proceso de fusión de los archivos hace que los mismos contengan dentro un caracter especial que indica el fin de cada archivo, este caracter es como una fecla apuntando a la izquierda; la idea es que despues que el proceso de merge esté completado hay que entrar en cada archivo y limpiarlos.

Sería mucho pedir esto?

De pana que muchisimas gracias chicos, son lo maximo.

Mad Antrax

No hago hacks/cheats para juegos Online.
Tampoco ayudo a nadie a realizar hacks/cheats para juegos Online.

Eleкtro

#19
Cita de: elqueteconte en 13 Octubre 2015, 16:53 PMEl proceso de fusión de los archivos hace que los mismos contengan dentro un caracter especial que indica el fin de cada archivo, este caracter es como una fecla apuntando a la izquierda

Eso lo puedes solucionar realizando una copia en modo binario:

Cita de: CMD.execopy /?
Copia uno o más archivos en otra ubicación.

 /A           Indica un archivo de texto ASCII.
 /B           Indica un archivo 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!