Redirigir el resultado de un comando a una variable ¿Se puede? ¿Cómo? [BATCH]

Iniciado por LoqiRex2, 16 Noviembre 2014, 15:52 PM

0 Miembros y 2 Visitantes están viendo este tema.

LoqiRex2

Buenas, gente. Es la primera vez que posteo algo en este foro así que no sé si lo estoy haciendo en la sección correspondiente y de la manera correcta.

Tengo un problema con un ejercicio de batch para el colegio secundario que estoy cursando:

Tengo un ejercicio donde tengo que condicionar a elegir entre 4 opciones. La primera es listar archivos según un criterio ingresado por el usuario; la segunda es copiar el resultado de la primera opción a un archivo de texto; la tercera es copiar el contenido de ese archivo de texto de la segunda opción a otro archivo de texto y la cuarta opción simplemente quitea el programa.

Como verán, la realización de las opciones que siguen a la primera están obligadas a realizarse ÚNICAMENTE si la primera opción se ha ejecutado antes. Eso no creo que sea un problema, con una variable adicional que cambie de valor una vez que se ejecuta la primera opción.
No obstante, el problema está en la primer opción. Ya tengo la estructura que evalúa la opción y lleva a la subestructura donde se pide que ingrese un nombre y una extensión para buscar archivos con esas características y ya lo he probado, es decir, se devuelve el resultado que busco. Pero ¿cómo hago para que éste resultado se almacene en una variable? ¿Se puede? De poderse, mi idea sería que para la segunda opción solo tendria que poner algo como "echo %resultado% >> archivo.txt"

Puedo hacer eso? si no puedo, qué otra cosa me recomiendan?. Muchísimas gracias!

Esta es la estructura que llevo hasta ahora (tiene declarada unicamente la subestrcutura de la primer opcion)

Código (dos) [Seleccionar]
@echo off
:menu
echo 1) listar archivos segun su criterio
echo 2) la busqueda anterior se almacena en un archivo
echo 3) copiar este archivo dentro del otro archivo de texto ingresado
echo 4) salir
set /p o= Elija su opcion:
if (%o%==1) goto :uno else(
if (%o%==2) and (%x%==1) goto :dos else (
if (%o%==3)  and (%x%==1) goto :tres else(
if (%o%==4) goto :cuatro)))

:uno
set /a x=1
set /p nar= Ingrese el nombre del archivo:
set /p exar= Ingrese su extension, si no conoce ecriba un arterisco:
dir /s C:\*%nar%*.%exar% >
pause
cls
goto :menu


:huh: :huh: :huh:

Eleкtro

Buenas!

CitarLa primera es listar archivos según un criterio ingresado por el usuario

Citarel problema está en la primer opción, ¿cómo hago para que éste resultado se almacene en una variable? ¿Se puede?

1) Te están pidiendo que listes archivos, no que almacenes el resultado de la búsqueda en una variable,
   sé que intentas ser eficiente pero en Batch no puedes serlo, así que mi consejo es que no hagas más de lo necesario, es decir, aquello que te piden que hagas.

2) Lamentablemente Batch no llega ni a poder calificarse como "lenguaje de programación", y las variables multi-linea no es una característica soportada (de forma natural) en Batch.
   Para crear una variable multilinea debes recurrir a un pequeño Hack, algo que te resultaría bastante engorroso en la situación que te encuentras (Dir + For /F + MultiLine Hack):
Código (dos) [Seleccionar]
@Echo OFF & SetLocal EnableDelayedExpansion

:: New Line Hack Start
set NewLine=^


:: New Line Hack End

set "MultiLine=Line1!NewLine!Line2"
set "MultiLine=!MultiLine!!NewLine!Line3"

Echo !MultiLine!

Pause&Exit


3) Consejo: Utiliza la programación en Inglés, el desarrollo en Castellano, además de feo, no es nada productivo.

Ejemplo:
Código (dos) [Seleccionar]
@Echo OFF

:Menu
Echo [1] Perform a file search in drive '%~d0\'.
Echo [2] Write the search result of option [1] to file.
Echo [3] *********
Echo [4] Terminate
Echo.
Choice.exe /C "1234" /M "Choose an option: "@Echo OFF & SetLocal EnableDelayedExpansion
Cls
Call :Option%ErrorLevel%
Cls
Goto :Menu

:Option1 :: Perform file search by pattern.
Set /P "SearchPattern.Filename=Write a partial filename: "
Set /P "SearchPattern.Extension=Write a file extension (or keep it empty for any extension): "

Set "SearchPattern.Drive=%~d0"
Set "SearchPattern.Filename=*%SearchPattern.Filename%*"  & :: Fix empty file name.
Set "SearchPattern.Extension=%SearchPattern.Extension%*" & :: Fix empty file extension.

(
Dir /A-D /B /S "%SearchPattern.Drive%\%SearchPattern.Filename%.%SearchPattern.Extension%"
)>"%Temp%\SearchResult.tmp"

Type "%Temp%\SearchResult.tmp" | MORE
Goto :EOF

:Option2 :: Save result to file.
If Not Exist "%Temp%\SearchResult.tmp" (
Echo There is any previous search result to save.
Pause
) Else (
Set /P "FileName=Set the destination filename: "
Call Move /Y "%Temp%\SearchResult.tmp" "%CD%\%%FileName%%.txt"
)
Goto :EOF

:Option3
:: Do Something.
Goto :EOF

:Option4
Exit


Saludos








LoqiRex2

Cita de: Eleкtro en 16 Noviembre 2014, 17:15 PM
Buenas!

1) Te están pidiendo que listes archivos, no que almacenes el resultado de la búsqueda en una variable,
   sé que intentas ser eficiente pero en Batch no puedes serlo, así que mi consejo es que no hagas más de lo necesario, es decir, aquello que te piden que hagas.

2) Lamentablemente Batch no llega ni a poder calificarse como "lenguaje de programación", y las variables multi-linea no es una característica soportada (de forma natural) en Batch.

3) Entiendo perfectamente esto, pero estoy evaluando el código con unos compañeros y algunos no manejan nada de inglés.


1) Sí, entiendo eso. Lo que pasa es que dentro de mi cabeza no se me ocurría otra posible solución mas que, después de obtener el resultado de la búsqueda, dejarlo almacenado en algún lugar al que pueda recurrir a la hora de realizar la opción 2.

2) Estuve leyendo tiempo después de haber posteado eso y caí en cuenta de eso.

Con el código que me preparó (muy amable de su parte, muchísimas gracias) puedo ejecutar la primer actividad, y al hacer la segunda solicita detallar dónde y con qué nombre va a ir el archivo ¿Verdad? Bueno, pues he ingresado C:\prueba1.txt y en C: no quedó ningún .txt con esa información. Lo más probable es que yo no esté entendiendo el código, porque a mitad de este año he empezado a programar con batch y, por ej., no conozco el comando choice. Hasta ahora, en las clases, solo hemos trabajado con if y de hecho la intención era realizar este ejercicio con if. Pero se me complica mucho (demasiado) la idea de anidarlos tantas veces. Es muy engorroso y es algo que suelo hacer en Pascal (otro lenguaje que estamos utilizando), pero en Pascal cuento con la ayuda de los Begin/end que puedo abrir bastantes veces uno dentro del otro. Aquí la cosa es demasiado engorrosa

Su código me ha servido para entender mejor cómo podría llegar a realizarlo, pero tampoco llego a comprenderlo totalmente. Estoy en un nivel muy inferior, demasiado.

Siguiendo la idea de hacerlo con los ifs (aunque quiero intentar entender al Choice, no me serviría para la clase), he ideado este código. Pero se ingresa a la primer opción y luego cuando ingreso a la segunda, entra nuevamente por la primera. ¿Qué hago?

Código (dos) [Seleccionar]
@echo off
:menu
echo 1) listar archivos segun su criterio
echo 2) la busqueda anterior se almacena en un archivo
echo 3) copiar este archivo dentro del otro archivo de texto ingresado
echo 4) salir
set /p o= Elija su opcion:
if (%o%==1) goto :uno else (if (%o%==2) (goto :if2) else (if (%o%==3) (goto :if3) else (if (%o%==4) (goto :cuatro) else (goto :error))))

:uno
del /s C:\artemp1.txt >> c:\artemp2.txt
set /a c=1
set /p nar= Ingrese el nombre del archivo:
set /p exar= Ingrese su extension, si no conoce ecriba un arterisco:
dir /s C:\*%nar%*.%exar% >> c:\artemp1.txt
type c:\artemp1.txt
pause
cls
goto :menu

:dos
set /a c=2
set /p noar1= Escriba el nombre del archivo de texto donde se va a guardar:
type c:\artemp1.txt >> c:\%noar%.txt
pause
cls
goto :menu

:tres
echo
set /p nombre2= Escriba el nombre del segundo archivo de texto destino:
type C:\%nombre1%.txt >> c:\%nombre2%.txt
pause
cls
goto :menu

:cuatro
echo
echo se saldra del programa
exit

:error
echo Ingreso algun nro fuera del rango o  intento realizar las opciones 2 y 3 sin hacer primero la 1 o la 2, respectivamente
pause
cls
goto :menu

:if2
if (%c%==1) goto :dos else(goto :error)

:if3
if (%c%==2) goto :tres else(goto :error)


La idea es que una vez que se ingrese a la primera opción, esta determine el resultado de la búsqueda (según los parámetros ingresados) y los guarde en un archivo temporal (el cual es borrado cada vez que se inicia este bloque :uno). De manera que si por alguna razón quisiera volver a entrar en la opción uno, muestre el resultado de la última búsqueda realizada y no de las anteriores. Ahora, si quisiese ingresar a la segunda opción la idea es que se evalúe si lo elegido es un 2. Si es asi, nos envía a otro bloque donde hay OTRO if el cual determina si se ejecutó o no la primera opción (por medio de una variable "contadora"), si fuese así, nos enviaría al bloque :dos (el cual tiene el bloque por el cual se guarda en un archivo con nombre a gusto del usuario. La tercera opción consiste en copiar el contenido del mismo archivo creado en la dos, a otro archivo,  y la manera de evaluar si se ejecutó la segunda opción ya es la misma que se utilizó en la segunda para determinar si se ejecutó la primera.

No entiendo qué hacer y traté de ser lo más claro posible en la explicación del algoritmo. Nuevamente, soy muy torpe con estas cosas. Es el segundo año que tengo programación y vengo de programar en pascal cosas tontas.



Eleкtro

Cita de: LoqiRex2 en 16 Noviembre 2014, 18:17 PM
al hacer la segunda solicita detallar dónde y con qué nombre va a ir el archivo ¿Verdad? Bueno, pues he ingresado C:\prueba1.txt y en C: no quedó ningún .txt con esa información. Lo más probable es que yo no esté entendiendo el código

Lo que ocurre es que en el bloque de la opción [2] pido el nombre del archivo, no pido la ruta completa ni tampoco la extensión, el archivo se guarda con el nombre especificado en el directorio de trabajo actual.

El código que escribí es un sólo ejemplo para orientarte y está abierto a modificaciones para adaptarlo a tus necesidades.






Cita de: LoqiRex2 en 16 Noviembre 2014, 18:17 PMse ingresa a la primer opción y luego cuando ingreso a la segunda, entra nuevamente por la primera.

El problema, obviamente, está aquí:
Citar
Código (dos) [Seleccionar]
if (%o%==1) goto :uno else (if (%o%==2) (goto :if2) else (if (%o%==3) (goto :if3) else (if (%o%==4) (goto :cuatro) else (goto :error))))

Estás intentando simular un 'ElseIf', pero esta es otra característica que no está soportada en Batch (aunque por otro lado si que soporta un 'And', pero de forma invisible).
No es necesario que anides los ifs para conseguirlo.

Cita de: LoqiRex2 en 16 Noviembre 2014, 18:17 PM¿Qué hago?

Tienes tres opciones:

1) usar múltiples If:
Código (dos) [Seleccionar]
If "%o%" EQU "1" (Goto :uno)
If "%o%" EQU "2" (Goto :dos)
etc...


2) Usar el comando Choice como ya mostré.

3) Omitir el uso de If y llamar al método deseado de forma dinámica:

Código (dos) [Seleccionar]
@echo off

:menu
cls
echo 1) listar archivos segun su criterio
echo 2) la busqueda anterior se almacena en un archivo
set /p "o= Elija su opcion:"
Call :%o%
Goto :Menu

:1
Echo Soy el método 1
pause
goto :EOF

:2
Echo Soy el método 2
pause
goto :EOF



saludos