Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: Orni1 en 16 Septiembre 2017, 13:49 pm



Título: el signo =
Publicado por: Orni1 en 16 Septiembre 2017, 13:49 pm
Vengo leyendo y aprendiendo del gran post http://foro.elhacker.net/scripting/acciones_sobre_archivos_de_texto_batch-t242748.0.html

pretendo cambiar un texto por otro, en el tema citado está este código:

Citar
@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims=" %%x in ('type texto.txt') do (
set linea=%%x
set linea=!linea:Perl=C!
call :show !linea!
)
goto:eof
:show
echo %* >> out.txt
goto:eof

El código funciona perfecto pero tengo un problema siguiendo con ejemplo mi texto seria

Perl=CCCC

y lo que quiero eliminar es Perl= y cambiarlo por HT de tal modo que en esa linea quede HTCCCC


Con ejemplo el código sería


Citar
@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims=" %%x in ('type texto.txt') do (
set linea=%%x
set linea=!linea:Perl==HT!
call :show !linea!
)
goto:eof
:show
echo %* >> out.txt
goto:eof

Pero no funciona por el signo =

¿Hay manera de escribir el signo = y que lo reconozca como texto no como parte del codigo?


Título: Re: el signo =
Publicado por: **Aincrad** en 16 Septiembre 2017, 19:52 pm
listo solo tienes que colocar el signo ^  para que te reconozca el = como texto.

asi:
Código
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=* delims=" %%x in ('type texto.txt') do (
  4. set linea=%%x
  5. set linea=!linea:Perl=^=ht!
  6. call :show !linea!
  7. )
  8. goto:eof
  9. :show
  10. echo %* >> out.txt
  11. goto:eof
  12.  
prueba el code a ver si es lo que quieres.


Título: Re: el signo =
Publicado por: Orni1 en 16 Septiembre 2017, 21:42 pm
Muchas gracias por el intento, pero a mi no me funciona. Eso me cambia el texto "Perl=" por "=ht="

Debería ser solo ht quitando el signo =

Por si sirve de algo estoy con win 10


Título: Re: el signo =
Publicado por: **Aincrad** en 16 Septiembre 2017, 22:29 pm
a ver, que es precisamente lo que quieres?


Título: Re: el signo =
Publicado por: Orni1 en 17 Septiembre 2017, 10:24 am
Que el signo = del texto original desparezca

En el texto original pone:
version=85045

Quiero que se cambie version= (incluyendo el =) por HT.

Quedando el texto así: HT85045


Título: Re: el signo =
Publicado por: **Aincrad** en 17 Septiembre 2017, 19:18 pm
ya lo he terminado. comenta si te funciono.

code:
Código
  1. @echo off
  2. set n=HT
  3. setlocal enabledelayedexpansion
  4. for /f "tokens=* delims=" %%x in ('type texto.txt') do (
  5. set linea=%%x
  6. set linea=!linea:version=%n%!
  7. call :show !linea!
  8. )
  9. goto foroelhacker.net
  10.  
  11. :foroelhacker.net
  12. Setlocal EnableDelayedExpansion
  13. Mode Con Cols=100 Lines=25
  14. If Exist "%TMP%\BMCTP" (
  15. Goto Inicio
  16. ) Else (
  17. MD "%TMP%\BMCTP"
  18. Goto Inicio
  19. )
  20.  
  21. :Inicio
  22. Set Ruta=%CD%
  23. CD %Ruta%
  24.  
  25. :Nombre_Texto
  26. Echo. & Echo =======================================================
  27. Echo Escriba el nombre del archivo a modificar (Solo archivos de texto plano "txt"):
  28. Set "Archivo=out"
  29. Cls
  30. If Not Exist "%Archivo%.txt" (
  31. Cls
  32. Echo No se ha encontrado el archivo solicitado, intente nuevamente.
  33. Goto Nombre_Texto
  34. ) Else (
  35. Cls
  36. Echo Archivo encontrado.
  37. Goto Backup
  38. )
  39.  
  40. :Backup
  41. Copy /Y "%Ruta%\%Archivo%.txt" "%TMP%\BMCTP\%Archivo%_Backup.txt" >nul
  42. If Exist "%TMP%\BMCTP\%Archivo%_Backup.txt" (
  43. Echo. & Echo =======================================================
  44. Echo Backup realizado con exito.
  45. >Nul Ping -n 3 Localhost & Cls & Goto Caracter
  46. ) Else (
  47. Cls
  48. Echo Error al hacer Backup del archivo.
  49. Pause>nul
  50. Exit
  51. )
  52.  
  53. :Caracter
  54. Set Caracter=^=
  55. If "%Caracter%" == "" Cls & Echo Por favor no intente ingresar valores nulos... & Echo. & Goto Caracter
  56. Cls & >Nul Ping -n 1 Localhost
  57.  
  58. :Mod
  59. Set PosX=0
  60. For /F "Usebackq Tokens=*" %%a IN ("%Ruta%\%Archivo%.txt") Do (
  61. Set Linea=%%a
  62. Call:Buscador
  63. Set "LineaNueva="
  64. )
  65. Goto Aprobacion
  66.  
  67. :Buscador
  68. If Not "%Caracter%" == "!Linea:~%PosX%,1!" (
  69. If "!Linea:~%PosX%,1!" == "" (
  70. Set PosX=0
  71. Echo !LineaNueva!>>"%TMP%\BMCTP\Nuevo_%Archivo%.txt"
  72. Goto:Eof
  73. )
  74. Set "LineaNueva=%LineaNueva%!Linea:~%PosX%,1!"
  75. Set /A PosX+=1
  76. Goto Buscador
  77. ) Else (
  78. If "!Linea:~%PosX%,1!" == "" (
  79. Set PosX=0
  80. Echo !LineaNueva!>>"%TMP%\BMCTP\Nuevo_%Archivo%.txt"
  81. Goto:Eof
  82. )
  83. Set /A PosX+=1
  84. Goto Buscador
  85. )
  86.  
  87. :Aprobacion
  88. Goto Fin
  89.  
  90. :Fin
  91. del /f /q out.txt
  92. Cls & Echo.
  93. Copy /Y "%TMP%\BMCTP\Nuevo_%Archivo%.txt" "%Ruta%\%Archivo%.txt" >nul
  94. >Nul Ping -n 1 Localhost
  95. Del /Q "%TMP%\BMCTP" >nul
  96. Echo El archivo modificado se encuentra en : "%Ruta%".
  97. Echo El archivo Back-Up se encuentra en : "%TMP%\BMCTP".
  98. Echo. & Echo Hemos terminado!
  99. Echo. & Echo Saliendo...
  100. >Nul Ping -n 2 Localhost & Exit
  101.  
  102. :show
  103. echo %* >> out.txt
  104. goto:eof
  105.  


lo que hace es buscar en el archivo texto.txt las palabras version=85045 y te las cambia a HT85045 . justo lo que querias ,

       comenta si te funciono   ;-)


Título: Re: el signo =
Publicado por: Orni1 en 17 Septiembre 2017, 22:30 pm
Ya lo creo que funcionó muchísimas gracias   ;-)  ;-)
Ademas es bonito y elegante. No solo me ha servido sino que voy a estudiarlo para aprender un poco mas aunque no os llego a suela del zapato.

**Aincrad** muchas gracias por tu tiempo y tu saber.


Título: Re: el signo =
Publicado por: **Aincrad** en 17 Septiembre 2017, 22:56 pm
dale no es nada.  :)

si no entiendes alguna parte de el code me avisas, con gusto te lo explicare.   ;)


Título: Re: el signo =
Publicado por: Eleкtro en 27 Septiembre 2017, 11:52 am
Hola. Batch no está pensado como un lenguaje (de hecho tecnicamente no es un lenguaje de programación) para parsear archivos de texto. En tu script, estás iterando linea por linea y tratando de realizar el reemplazamiento de string en cada una de las lineas, aparte de eso en lugar de escribir de una sola vez el archivo, estás adjuntando la última linea iterada al final del archivo de texto, todo esto en términos de rendimiento/velocidad de ejecución deja mucho que desear, y el agravío lo notarías si se tratase de un archivo con varios miles de lineas...

En fin, a donde quiero llegar es que Batch está desfasado para este tipo de tareas, y hay que ir inculcando a las nuevas generaciones la forma más óptima de resolver ciertos problemas, por eso en lugar de Batch yo te sugiero utilizar PowerShell.

La solución a tu problema:

script.ps1
Código
  1. [System.Reflection.Assembly]::LoadWithPartialName("System.Text.dll")
  2.  
  3. $srcFilePath  = ".\Iput Text.txt"
  4. $dstFilePath  = ".\Output Text.txt"
  5. $textEncoding = [System.Text.Encoding]::Default
  6.  
  7. $filecontent  = [System.IO.File]::ReadAllText($srcFilePath, $textEncoding)
  8. $replacedText = ($filecontent).Replace("Perl=", "HT")
  9.  
  10. [System.IO.File]::WriteAllText($dstFilePath, $replacedText, $textEncoding)
  11.  
  12. Write-Host $replacedText
  13. Exit(0)

Saludos.


Título: Re: el signo =
Publicado por: Orni1 en 27 Septiembre 2017, 23:03 pm
Muchas gracias Elektro.
Mi problema es tengo una base muy pequeña con batch y pese a que no entiendo la mayoría de las cosas fuera de los comandos simples, con la lectura en el foro y copiando los aportes de otros usuarios soy capaz de construir algo medianamente funcional que seguro no es nada correcto pero llega a funcionar. De otro modo lo que tu presentas para mi es totalmente desconocido.

Mi desconocimiento es tal que todavía no soy capaz de saber como es posible que el código del compañero funcione y me quite los signos "=" así que imagina la importancia que para mi pueden tener unos segundos mas o menos cuando antes no podía hacerlo correr de ningún modo.

Te reirías si supieras los meses que llevo dando vueltas al código tratando de hacerlo por mi cuenta y para tener algo que mostrar a la hora de preguntar, para mi ya solo con que me quite los signos de = es un triunfo de muchas horas de trabajo por mi incapacidad en este terreno pero voy aprendiendo.

Entiendo que es un código obsoleto y que hay otras opciones mas actuales y mejores, pero si tengo que ir a algún sitio y me das la opción de conducir en mi coche viejo o en el deportivo mas potente y mas moderno elegiré el coche viejo que aunque no soy piloto se como conducirlo mas o menos.

Si que te agradeceré algún enlace donde poder iniciarme en Power Shell porque me gusta aprender y ademas que me indiques como hago uso de lo que propones, quiero decir... copio el código lo pego en un archivo de texto y que extensión debo ponerle.


Título: Re: el signo =
Publicado por: Eleкtro en 28 Septiembre 2017, 01:28 am
Entiendo que es un código obsoleto y que hay otras opciones mas actuales y mejores

Bueno, "obsoleto" es un término muy...peliagudo y más de una vez me han criticado por llamar obsoleto a las cosas, así que dejémoslo en "insuficiente". Simplemente Batch no da la talla necesaria para cubrir ciertas necesidades de forma eficiente...



Mi desconocimiento es tal que todavía no soy capaz de saber como es posible que el código del compañero funcione

Sinceramente no me entusiasma ponerme a analizar y desglosar códigos espagueti y menos escritos en Batch, pero lo haré para intentar ayudarte a que trates de discernir por ti mismo la gravedad del asunto:

Empecemos por la parte más relevante del código, estas lineas:

Citar
Código:
@echo off
set n=HT
setlocal enabledelayedexpansion
for /f "tokens=* delims=" %%x in ('type texto.txt') do (
set linea=%%x
set linea=!linea:version=%n%!

En esta variable se define el reemplazamiento ("HT")
Citar
Código
  1. set n=HT

Luego, lo que se hace es utilizar un búcle de tipo For /Files para iterar las lineas del texto. Cada linea de texto se almacena en la variable de For %%x:
Citar
Código
  1. for /f "tokens=* delims=" %%x in ('type texto.txt') do (...

Cada linea se reasigna en la variable !linea!
Citar
Código
  1. set linea=%%x
...es decir, aquí tanto el valor de la variable de For %%x como de la variable "linea" es: "version=85045"

Seguidamente se lleva a cabo un string replacement (el reemplazamiento de texto) en el que se le indica que se debe reemplazar el texto "versión" (recuerda que esto se hace en todas las lineas) por el valor de la variable %n%, es decir, "HT":
Citar
Código
  1. set linea=!linea:version=% style="color: #448888;">n%!
...y es aquí donde la linea de texto pasa a ser de "version=85045" a "HT=85045".

Ese reemplazamiento de por si ya es un fallo muy grave, puesto que dará falso positivo / resultados indeseados en cualquier linea que contenga el texto "version". Por ponerte un ejemplo, esto:
Código:
texto_Version_texto=85045
Será convertido a esto otro:
Código:
texto_HT_texto85045

Bueno, sigamos...

El caracter del símbolo igual = se define más tarde en esta variable:
Citar
Código
  1. Set Caracter=^=
...esto de por si es una práctica no recomendable en Batch que pone en peligro posibles fallos de sintaxis en futuras evaluaciones, puesto que la variable no está encerrada entre comillas dobles. Debería haber sido declarada de la siguiente manera:
Código:
Set "Caracter=="
...no es necesario escapar el caracter.

Luego, en la rutina :Buscador se itera cada caracter de la linea, es decir, se va procesando cada caracter hasta encontrar el caracter que coincida con la variable "%caracter%", es decir, el símbolo de igual =.
De nuevo aquí se usa una mala práctica además de ser muy peligrosa (y de verdad), la Recursividad, esto es cuando una función se llama así misma de forma indefinida para resolver un problema ( en el código: Goto Buscador ). Esto quiere decir que si usases ese algoritmo recursivo (la rutina :Buscador del script de @Aincrad) sobre un archivo con muchas (pero muchas) lineas de texto/caracteres, inevitablemente desembocaría en un error conocido como Stack Overflow, el cual indica un agotamiento de espacio en la capacidad de almacenamiento de la pila de llamadas por un exceso de llamadas (como resulta evidente), y este error imposibilitaría que el programa/algoritmo pudiese proseguir y finalizar su ejecución.

..Por no decir que para cumplir el objetivo de reemplazar un texto se han tenido que escribir ni más ni menos que 104 lineas de código en Batch, compañero, 104. Fíjate en las 10 simples lineas que te ofrece el lenguaje PowerShell para llevar a cabo la misma tarea y de forma mucho más estable. Ojo, no estoy insinuando que esto tenga que ver con la forma de programar y estructurar/organizar del compañero @Aincrad (bueno, un poco si xD, el código se puede simplificar mucho) sino con las limitaciones por naturaleza que implica el uso de Batch, donde en otros lenguajes son 10 lineas, en Batch serán 100... e imperfectas.

Eso son solo algunos de las muchos problemas que uno tiene que sufrir al trabajar con Batch, es horrible e inestable realizar este tipo de tareas en Batch, por que Batch no fue diseñado para esto, pero la gente se acostumbra y se acostumbra y se creen que les vale para todo... todo lo quieren hacer con Batch, incluso, cuando NO SE PUEDE (o se puede, pero MAL... de forma inestable).



Mira, para que puedas tener una alternativa a la solución de @Aincrad, te voy a enseñar un código que desarrollé hace mucho tiempo y quizás podría servirte para llevar a cabo modificaciones de archivos de texto en Batch como reemplazar texto de forma sencilla:

  • [BATCH] [APORTE] Rutina TEXTMAN para manipular archivos de texto - by Elektro (http://foro.elhacker.net/scripting/batch_aporte_rutina_textman_para_manipular_archivos_de_texto-t372497.0.html)

El código entero lo copiarias dentro de tu script, abajo del todo, tal que así:
Código
  1. @Echo OFF
  2. REM Aquí los comandos originales de tu script...
  3. Echo Hello World !!
  4. REM ...
  5.  
  6. REM Aquí abajo insertas todo el código de la rutina :TEXTMAN
  7. :TEXTMAN
  8. REM ...

y la sintaxis de utilización sería la siguiente:
Código:
Call :TEXTMAN RSA "Archivo.txt" "Perl=" "HC"

...pero hace años que no utilizo ese código del demonio, no sé si estará del todo libre de bugs, y no lo pienso revisar (siendo un código escrito en el odioso Batch xD).



si tengo que ir a algún sitio y me das la opción de conducir en mi coche viejo o en el deportivo mas potente y mas moderno elegiré el coche viejo que aunque no soy piloto se como conducirlo mas o menos.

Es una decisión tan respetable como cualquier otra, pero piensa que el "coche" antiguo siempre manifestará algún tipo de problemas: se atascarán las marchas, el cuentakilómetros irá mal, el retrovisor no encajará bien, tendrás que darle golpecitos a la puerta para que se cierre del todo, te sentirás escaso de accesorios útiles en su interior... etcétera. El "coche" antiguo te podrá hacer sentir muy cómodo por esa sensación de familiaridad, pero eso no quita la realidad, y la realidad es que es inevitable que lo antiguo se desgaste y se invente algo que lo supere con creces, algo actual, más completo y sofisticado mientras que lo antiguo se desgasta, y ese desgaste (u obsolescencia) solo conseguirá que tus movimientos sean excesivamente torpes en comparación con lo que actualmente tienes a tu disposición (lo "moderno")...

De todas formas, si migrases a PowerShell no sería lo equivalente a comprarse el mejor coche deportivo del mundo, sino más bien sería como comprarse un coche mucho mejor que el coche antiguo para estos tiempos que corren, y sin perder esa relación de...manejo o aprendizaje amistoso.

Una de las muchas ventajas que supondría aprender otro lenguaje de programación... y ya no me estoy refiriendo a PowerShell, sino AL QUE SEA, seria darte cuenta de como lo que para desarrollar un algoritmo en Batch puede suponer escribir 100 lineas (que además serían 100 lineas de código espagueti e inestable), en ese otro lenguaje podrías simplificarlo a 10 lineas... con la diferencia y el ahorro de tiempo que eso conlleva, entre otras cosas.
Luego hay otros beneficios como las características de depuración de código o el soporte de un paradigma orientado a objetos, son cosas que no serían tan perceptibles para una persona que se acabe de iniciar en la programación o que no sepa mucho, pero siguen siendo cosas que en Batch tampoco tienes y te están limitando...sin que sepas demasiado bien el por qué.

No intento convencerte de nada xD pero quería darte mi opinión al respecto para que lo pudieras reflexionar desde la perspectiva adecuada (no sé si lo habré conseguido). Si yo quisiera recomendarte lo que considero el "mejor" lenguaje entonces no sería PowerShell (sería VB.NET o C#), PowerShell es el lenguaje que te recomiendo si quieres un lenguaje de scripting que no necesite instalar ningún "intérprete" adicional en Windows y con el que poder programar scripts sencillos o avanzados, me refiero, poder hacer de todo con libertad, estabilidad y sofisticación (sin duda infinitamente más que en Batch y VBS... en todos los sentidos posibles).

También debo decir que por supuesto para escribir scripts de forma esporádica para resolver algún problemilla como éste de reemplazar lineas de texto pues... no necesitas realizar el tremendo esfuerzo de aprender un nuevo lenguaje, pero si en el futuro sigues necesitando realizar tareas como esta entonces te convendría aprender, sino PowerShell entonces como mínimo Visual Basic Script (el cual sería un lenguaje más capacitado que Batch, pero menos que PowerShell), y esos meses que has pasado "atascado" en Batch probablemente habrían sido unas pocas horas o unos cuantos dias en uno de esos lenguajes...



que me indiques como hago uso de lo que propones, quiero decir... copio el código lo pego en un archivo de texto y que extensión debo ponerle.

Si te fijas bien en mi comentario, justo arriba del bloque de código escribí "script.ps1", pues bien, ese "ps1" hace referencia a la extensión del archivo. Si, simplemente copia y pega el código en un archivo de texto y lo guardas con extensión "ps1".

En esta linea especificarías la ruta del archivo de origen (el archivo que contiene el texto "Perl="):
Citar
Código
  1. $srcFilePath  = ".\Iput Text.txt"

En esta linea especificarías la ruta del archivo de destino, es decir, el archivo donde se van a escribir el texto con los cambios/reemplazamientos hechos:
Citar
Código
  1. $dstFilePath  = ".\Output Text.txt"

Esta linea no creo que necesites modificarla, y además creo que habla por si sola... el primer argumento de la función "Replace" es el texto a reemplazar ("Perl="), y el segundo argumento es el texto por el cual será reemplazado ("HT"):
Citar
Código
  1. $replacedText = ($filecontent).Replace("Perl=", "HT")

¿Cómo utilizar el archivo/script?, pues sencillamente haciendo click derehcho sobre el archivo -> Ejecutar con PowerShell. O bien puedes abrir una instancia de la consola de Windows (CMD.exe) para iniciar la consola de Powershell tal que así:

Código
  1. @Echo OFF
  2. PowerShell.exe "C:\Ruta absoluta del script.ps1"



algún enlace donde poder iniciarme en Power Shell

¿Cómo llevas el dominio del idioma Inglés?, la mayor fuente de documentación así como guías/tutoriales de introducción para iniciarse en el lenguaje y basicamente todo lo que necesitas aprender al respecto (incluyendo porsupuestísimo la referencia de los miembros del lenguaje al completo) lo puedes encontrar en la famosa web MSDN.com de Microsoft y la nueva docs.microsoft.com, eso sí, en perfecto Inglés:

  • https://docs.microsoft.com/en-us/powershell/
  • https://msdn.microsoft.com/en-us/library/ms714469%28v=vs.85%29.aspx?

Muchos artículos tanto en la MSDN como en docs.microsoft.com están en Castellano, tan solo tienes que modificar la dirección URL para reemplazar la localización del idioma "en-us" por "es-es", por ejemplo:
  • https://docs.microsoft.com/en-us/powershell/scripting/getting-started/getting-started-with-windows-powershell?view=powershell-5.1 (https://docs.microsoft.com/en-us/powershell/scripting/getting-started/getting-started-with-windows-powershell?view=powershell-5.1)
  • https://docs.microsoft.com/es-es/powershell/scripting/getting-started/getting-started-with-windows-powershell?view=powershell-5.1 (https://docs.microsoft.com/es-es/powershell/scripting/getting-started/getting-started-with-windows-powershell?view=powershell-5.1)
...pero la mayoría de artículos no están traducidos, te aviso.

Y luego en la galería de códigos de Technet puedes encontrar pues... eso, muchos scripts de programadores profesionales de PowerShell que puedes descargar para aprender analizando el código fuente:
  • https://gallery.technet.microsoft.com/scriptcenter/site/search?f%5B0%5D.Type=ProgrammingLanguage&f%5B0%5D.Value=PowerShell&f%5B0%5D.Text=PowerShell

( la gran mayoría de scripts que encontrarás ahí están enfocados a la administración web puesto que el propósito de utilización principal del lenguaje Powershell es la administración de servidores web, por otro lado Batch / CMD es un simple instrumento desarrollado con el único propósito de cubrir una interoperabilidad muy básica por no decir cutre, pobre e INUTIL entre el usuario y la shell de Windows, ofreciendo así la posibilidad de poder llevar a cabo tareas básicas (insisto en lo de BÄSICAS, muy, muy básicas, por que es así, Batch no da para más) de administración del sistema operativo y sistema de archivos en general; eso no quita que puedas y debas usar Powershell como reemplazamiento del antiguo Batch y cubrir todas esas cosas que en Batch resultarían muy tediosas o engorrosas de llevar a cabo. )

Bueno, creo que para variar he escrito un monólogo demasiado extenso... lo siento, pero no me gusta dejarme ningún detalle importante sin su debida aclaración.

Un saludo.


Título: Re: el signo =
Publicado por: **Aincrad** en 28 Septiembre 2017, 01:54 am
 :o . Elektro le escribiste un testamento .. ..  :o  :laugh:  ;D


Título: Re: el signo =
Publicado por: Orni1 en 28 Septiembre 2017, 09:43 am
Madre mía, ya hay donde leer muchísimas gracias primero por tu extensión en el análisis, segundo por tus sabios consejos y tercero por la voluntad de ayuda y tu tiempo.

Comentar que el texto a tratar siempre va ser de 5 ó 6 lineas por lo que se acota bastante el posible error no obstante probaré a modificar el código para incluir el tuyo nuevo como indicas y para aprender alguna cosa mas.

Gracias a los dos, Elektro y **Aincrad**.  ;-)


Título: Re: el signo =
Publicado por: Orni1 en 1 Octubre 2017, 14:37 pm
Estoy tratando de usar el ps1 de Elektro para mi código.
El primer problema que he tropezado es con los permisos de ejecución de script power shell en el pc ya que la llamada

Código:
    @Echo OFF
    PowerShell.exe "C:\Ruta absoluta del script.ps1"

No funciona.

Investigando el tema he llegado a la conclusión que es problema de permisos ya que cada vez que ejecuto el ps1 --> botón derecho ejecutar con PS la consola pide permiso para la ejecutar ese script.

He descubierto que la llamada desde cmd se puede hacer así (igual le sirve a alguien):

Código:
@Echo OFF
PowerShell.exe -ExecutionPolicy Bypass -Command "& Ruta absoluta del script" >nul

Hasta ahí he llegado bien, ahora el problema que me surge y no soy capaz de encontrar solución, es
la gestión de la ruta. El script rula bien si pongo todos los archivos en el mismo directorio pero mi código.bat estaba dirigido a la ruta %temp%\ttdje la ruta con la variable %temp% la tengo clara en cmd pero pero como se escribe la ruta   %temp%\ttdje en power shell, porque poniendo la ruta absoluta va bien, pero me gustaría poner la variable de la carpeta temp pero no se como se redacta en Power Shell y esto ya se que no rula:

Código:
@Echo OFF
PowerShell.exe -ExecutionPolicy Bypass -Command "& %temp%\ttdje\script.ps1" >nul

Imagino que el problema es que las variables de ruta no se escriben igual y en esa llamada, pese a ser desde cmd la variable de temp deberá ir escrita para PowerShel.



Título: Re: el signo =
Publicado por: Eleкtro en 1 Octubre 2017, 18:23 pm
Código:
@Echo OFF
PowerShell.exe -ExecutionPolicy Bypass -Command "& %temp%\ttdje\script.ps1" >nul

La llamada con la sintaxis que estás utilizando funciona correctamente, no sé exactamente que supuesto error dices estar teniendo... podrías intentar explicarlo de otro modo. De todas formas en caso de error PowerShell te mostrará información respecto a ese error... muestranos la información de ese error.

Supongo que esto no será lo que te ocurre, pero por si acaso: si el problema es que en tu equipo has modificado el valor de la variable de entorno TEMP y ésta apunta a una ruta con espacios en blanco, o si en realidad la carpeta "ttdje" o el archivo "script.ps1" no se llama así y es un nombre con espacios en blanco entonces tienes que encerrar la ruta entre comillas dobles...y esas comillas dobles debes escaparlas en el argumento. Ejemplo:

Código:
PowerShell.exe "& \"%TEMP%\ttdje\script.ps1\" "

Saludos.


Título: Re: el signo =
Publicado por: Orni1 en 1 Octubre 2017, 21:09 pm
Lo he dicho mal porque ni yo misma lo entendía

Tengo el bat ejecutando en "E:\PS\prueba_descomprime", con la llamada mencionada que si que rula.

Pero lo que no se es escribir la variable en el script.ps1 el script está así:

Código:
    [System.Reflection.Assembly]::LoadWithPartialName("System.Text.dll")
     
    $srcFilePath  = ".\temp.txt"
    $dstFilePath  = ".\temp2.txt"
    $textEncoding = [System.Text.Encoding]::Default
     
    $filecontent  = [System.IO.File]::ReadAllText($srcFilePath, $textEncoding) 

    $replacedText = ($filecontent).Replace(".zip", "")
 
    [System.IO.File]::WriteAllText($dstFilePath, $replacedText, $textEncoding)
     
    Write-Host $replacedText

    Exit(0)

Ejecutado el script con el botón derecho funciona bien porque lo ejecuto en la carpeta temporal: "C:\Users\YO\AppData\Local\Temp\ttdje"

Pero realizando la llamada desde el bat lo único que hace es crear un archivo temp2 vacío en la ubicación del bat.
Solución a esto es poner la ruta en el script y entonces si que rula.

Pero si me llevo el código a otro pc ya no rula porque la ruta que tiene temp es diferente, la solución es poner la ruta %Temp% en el script.ps1 en forma de variable en vez de ruta absoluta eso es lo que no se como hacer cuál es la redacción de la ruta "%TEMP%\ttdje\temp.txt" en Power Shell










Título: Re: el signo =
Publicado por: Eleкtro en 1 Octubre 2017, 22:00 pm
la solución es poner la ruta %Temp% en el script.ps1 en forma de variable en vez de ruta absoluta eso es lo que no se como hacer cuál es la redacción de la ruta "%TEMP%\ttdje\temp.txt" en Power Shell

Ejecutado el script con el botón derecho funciona bien porque lo ejecuto en la carpeta temporal: "C:\Users\YO\AppData\Local\Temp\ttdje"

Pero realizando la llamada desde el bat lo único que hace es crear un archivo temp2 vacío en la ubicación del bat.

Ah, bueno, ahora entiendo lo que dices. Lo que te sucede es que no has modificado el directorio de trabajo del executable PowerShell.exe antes de iniciarlo. Por defecto, el directorio de trabajo será el mismo directorio de trabajo de tu batch-script, por eso el script de PowerShell te crea un archivo en el directorio donde tienes ubicado el archivo .bat.

Puedes modificar el directorio de trabajo actual antes de ejecutar PowerShell.exe desde Batch con el comando PUSHD (o en su defecto el comando CD):
Código
  1. @Echo OFF
  2. PUSHD "%TEMP%\ttdje"
  3. PowerShell.exe "& \"%CD%\script.ps1\" "

O bien puedes modificarlo después en el script de PowerShell utilizando el cmdlet Set-Location:
Código
  1. Set-Location ([System.IO.Path]::GetTempPath() + "ttdje")
  2. Write-Host (Get-Location)
  3.  
  4. $srcFilePath  = ".\temp.txt"
  5. $dstFilePath  = ".\temp2.txt"
  6. # etc ...

PD: O también podrías hacer que el script recoja los argumentos command-line para indicarle una ruta específica y que la asigne como directorio de trabajo, pero con las dos soluciones de arriba es más que suficiente.

Saludos.


Título: Re: el signo =
Publicado por: Orni1 en 2 Octubre 2017, 12:49 pm
Esta llamada funciona bien con el script como estaba y tambien modificandolo como me dices:
Código:
    @Echo OFF
    PUSHD "%TEMP%\ttdje"
    PowerShell.exe "& \"%CD%\script.ps1\" "
    POPD



Modificando el script y con la llamada vieja en el bat que teníamos, no rula:

Código:
    Set-Location ([System.IO.Path]::GetTempPath() + "ttdje")
    Write-Host (Get-Location)
 
    $srcFilePath  = ".\temp.txt"
    $dstFilePath  = ".\temp2.txt"
    [System.Reflection.Assembly]::LoadWithPartialName("System.Text.dll")

    $textEncoding = [System.Text.Encoding]::Default
     
    $filecontent  = [System.IO.File]::ReadAllText($srcFilePath, $textEncoding) 

    $replacedText = ($filecontent).Replace(".zip", "")
 
    [System.IO.File]::WriteAllText($dstFilePath, $replacedText, $textEncoding)
     
    Write-Host $replacedText

    Exit(0)

... así tampoco

Código:
    Set-Location ([System.IO.Path]::GetTempPath() + "ttdje")
    Write-Host (Get-Location)
 
    $srcFilePath  = ".\temp.txt"
    $dstFilePath  = ".\temp2.txt"

    $textEncoding = [System.Text.Encoding]::Default
     
    $filecontent  = [System.IO.File]::ReadAllText($srcFilePath, $textEncoding) 

    $replacedText = ($filecontent).Replace(".zip", "")
 
    [System.IO.File]::WriteAllText($dstFilePath, $replacedText, $textEncoding)
     
    Write-Host $replacedText

    Exit(0)

Dejo el bat con esta llamada:

Código
  1.    @Echo OFF
  2.    PUSHD "%TEMP%\ttdje"
  3.    PowerShell.exe "& \"%CD%\script.ps1\" "
  4.    POPD

y el script así:

Código
  1.    Set-Location ([System.IO.Path]::GetTempPath() + "ttdje")
  2.    Write-Host (Get-Location)
  3.  
  4.    $srcFilePath  = ".\temp.txt"
  5.    $dstFilePath  = ".\temp2.txt"
  6.    [System.Reflection.Assembly]::LoadWithPartialName("System.Text.dll")
  7.  
  8.    $textEncoding = [System.Text.Encoding]::Default
  9.  
  10.    $filecontent  = [System.IO.File]::ReadAllText($srcFilePath, $textEncoding)  
  11.  
  12.    $replacedText = ($filecontent).Replace(".zip", "")
  13.  
  14.    [System.IO.File]::WriteAllText($dstFilePath, $replacedText, $textEncoding)
  15.  
  16.    Write-Host $replacedText
  17.  
  18.    Exit(0)

Así funciona.