es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo procesar un comando de varias líneas dentro de un bucle for /f?

Contexto

Estoy intentando desarrollar un script que unifique mis scripts de trabajo actual para analizar algunos archivos de video. El primero es muy simple, solo se asegura de que todos los archivos de video estén en contenedores mkv. Los siguientes algunos llaman a mkvmerge -i para verificar si el archivo tiene subtítulos, etiquetas, adjuntos y otros extras no deseados que se eliminan a veces usando find, a veces usando findstr para la expresión regular (RegEx).

Esto es cómo se ve la salida de mkvmerge -i:


Archivo 'test.mkv': contenedor: Matroska
ID de pista 0: video (AVC/H.264/MPEG-4p10)
ID de pista 1: audio (Opus)
ID de pista 2: subtítulos (SubRip/SRT)
ID de adjunto 1: tipo 'image/jpeg', tamaño 30184 bytes, nombre de archivo 'test.jpg'
ID de adjunto 2: tipo 'image/jpeg', tamaño 30184 bytes, nombre de archivo 'test2.jpg'
ID de adjunto 3: tipo 'image/jpeg', tamaño 30184 bytes, nombre de archivo 'test3.jpg'
Capítulos: 9 entradas

Actualmente, simplemente lo redirecciono a find o findstr y busco palabras como “subtítulos”, “bytes” o : [0-9].

Mi objetivo es, para cada archivo procesado, llamar a mkvmerge -i solo una vez por archivo en lugar de una vez por cada script por el que pasa. Este es un proyecto antiguo que estoy retomando y mi intento anterior se puede ver en esta pregunta.

La pregunta

Siguiendo esta respuesta, logré agregar la salida de mkvmerge -i a una variable (%mkvmergeinfo%) y ahora todo lo que tengo que hacer es redirigir esta variable unas cuantas veces y hacer que el resto del código actúe en consecuencia. Esto es lo que parece actualmente:

lang-cmd
for /f "usebackq delims= eol=$" %%c in (echo !mkvmergeinfo! ^| find /c /i "subtitles") do (
if [%%c]==[0] (
...

Si cambio echo !mkvmergeinfo! por mkvmerge -i, el resto del código funciona correctamente, pero como ahora estoy intentando pasar un comando multilinea, cuando agrego echo %%c después de do, solo muestra la primera línea de echo !mkvmergeinfo! (que ya verifiqué y contiene todas las líneas).

Intenté resolver esto reemplazando todo el comando dentro de los paréntesis por una llamada a una etiqueta, que haría el echo y la redirección, pero eso no funcionó.

¿Existe otra manera de resolver este problema sin escribir la salida en un archivo y en lugar de ello analizar ese archivo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en Windows, bucles for y archivos por lotes, hay una forma de solucionar el problema de pasar un comando de varias líneas en el escenario dado. En lugar de utilizar echo !mkvmergeinfo! como un comando, podemos usar set /p mkvmergeinfo= para leer la salida de mkvmerge -i y guardarla en una variable. Luego, podemos utilizar esta variable para procesarla posteriormente dentro del bucle for, de la siguiente manera:

    set /p mkvmergeinfo=< <(mkvmerge -i)
    for /f "usebackq delims= eol=$" %%c in (`echo !mkvmergeinfo! ^| find /c /i "subtitles"`) do (
        if [%%c]==[0] (
            ...
    

    Esto lee la salida de mkvmerge -i y la guarda en mkvmergeinfo utilizando el operador <. Luego, podemos utilizar esta variable como lo haríamos con echo !mkvmergeinfo!, y el bucle for debería funcionar correctamente.

Comments are closed.