2010-04-02 14 views
5

Estoy tratando de leer algo de información de un archivo de texto mediante el uso de línea de comandos de Windows, y guardarlo en una variable como "set info = 1234"de comandos por lotes de DOS para leer algo de información de archivo de texto

A continuación se el contenido del archivo txt, en realidad solo necesito el número de revisión, y la ubicación siempre es la misma línea 5, y de la columna 11 a 15. En la muestra es 1234, y me pregunto si hay alguna manera de ahorrar a una variable en la línea de comando Dos.

¡Muchas gracias!

svninfo.txt:

Path: . 
URL: https://www.abc.com 
Repository Root: https://www.abc.com/svn 
Repository UUID: 12345678-8b61-fa43-97dc-123456789 
Revision: 1234 
Node Kind: directory 
Schedule: normal 
Last Changed Author: abc 
Last Changed Rev: 1234 
Last Changed Date: 2010-04-01 18:19:54 -0700 (Thu, 01 Apr 2010) 

Respuesta

11

Aquí hay una versión de una línea:

for /f "tokens=2" %%i in ('findstr Revision: input.txt') do set revision=%%i 
  1. findstr se usa para f ilter el archivo. Imprimirá "input.txt: Revisión: 1234"
  2. Luego, "tokens = 2" significa que estamos interesados ​​en el segundo token, "1234". Por defecto para descansos en espacios en blanco.
+0

¡Muy listo! Me olvidé de Findtr. –

+0

Para agregar a esto: Probablemente deberías usar una coincidencia de expresiones regulares y anclar la cadena 'Revision:' al comienzo de la línea. Nunca sabrá si no aparecerá en otros lugares :-) – Joey

+0

@Johannes quiere que use 'fidnstr/R' para habilitar la expresión regular. –

4

El siguiente fragmento de código muestra cómo hacer esto:

@echo off 
setlocal enableextensions enabledelayedexpansion 
set revision= 
for /f "delims=" %%a in (input.txt) do (
    set line=%%a 
    if "x!line:~0,10!"=="xRevision: " (
     set revision=!line:~10! 
    ) 
) 
echo !revision! 
endlocal 

Su salida es 1234 lo deseas.

El setlocal es lo que uso en cada secuencia de comandos para garantizar que las variables se traten de forma conocida. La instrucción for procesa cada línea en el archivo de entrada (el bit delims detiene la línea para que no se convierta en palabras separadas).

Los bits !line:~ son subcadenas con !line:~0,10! siendo los primeros diez caracteres y !line:~10! siendo el resto.

Así que, básicamente, comprueba cada línea para ver si comienza con "Revision: " y, si es así, extrae el resto de la línea para más adelante.

+0

Muchas gracias! Funciona. – Ray

+0

Yo personalmente iría con la variante 'findstr', sin embargo. Hace que el intento sea mucho más claro y es un poco más corto ya que no tiene que verificar el inicio de la línea con subcadenas. – Joey

+0

Ha pasado un tiempo, pero IIRC me gusta poner '@ SETLOCAL' en la primera línea, por lo que el' @ECHO OFF 'no afecta la configuración del eco de un script de llamada. Además, me gusta reemplazar el '@ECHO OFF' con' @IF NOT DEFINED _ECHO ECHO OFF', por lo que puedo usar 'SET _ECHO = 1' para depurar mis scripts. –

2

utilizar el comando for para analizar el archivo:

for /f "skip=4 tokens=2" %%l in (svninfo.txt) do (
    set revision=%%l 
    goto gotrev 
) 

:gotrev 
echo revision is %revision% 
+0

Bastante succint este! :) –

+0

Sucinta, sí, pero la versión de paxdiablo es probablemente una mejor opción, ya que en realidad comprueba la conformidad de los datos que va a devolver, en lugar de basarse solo en un número de línea. –

1

si usted tiene puede utilizar herramientas GNU, como gawk

@echo off 
for /F %%a in ('gawk -F":" "$1~/Revision/{print $2}" file') do (
     set var=%%a 
) 
echo %var% 
1

Saber cómo usar el scripting CMD con destreza es genial, pero el uso de PowerShell es aún mejor. He aquí una manera de hacerlo:

$revision = ((gc .\svninfo.txt | ? { $_.StartsWith('Revision: ') }) -split ' ')[1] 

¿Qué está pasando?

$revision es una variable

gc es Get-Content, también conocido como type. Cada línea en el archivo se convierte en una cadena en una secuencia (tubería).

? es Where-Object. Filtra los objetos en una tubería en función de una condición.

{} delimita un bloque de script

$_ es el objeto actual en la tubería.

-split invoca String.Split() en .NET, que le da una gran variedad de objetos

[1] índices en la matriz a

Cuestiones relacionadas