windows - forgrening på program output i en batch fil

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har ligget fast på dette i et stykke tid og forvirrer mig yderligere ved at kigge på hjælpesider om, hvordan man programmerer i batch.


Konteksten er, at jeg vil identificere, hvilke filer i en mappe der er gyldige xml, og tilføj alle de ugyldige filer til en bestemt fil for yderligere behandling.


Gør det, jeg bruger xmlstarlet og bruger kommandoen nedenfor. Jeg har kunnet identificere, hvilke der er gyldige, og rør output til min batchfil.


xml val *.xml | myscript.bat


Nu, hvad jeg vil gøre, er at identificere, hvilke der er gyldige, for at gøre det skal jeg analysere output fra xml.exe, som er følgende:


20100319.xml - valid
20090915.xml - valid
20090915.xml - valid
20090915.xml - valid
20090915.xml - invalid


Så hvad jeg faktisk har brug for er at gren på hver linje for at se om de sidste 7 tegn er 'ugyldige' eller ej, hvis ja, tilføj xml-filen til min resultatfil.


Forsøger gør det, jeg byggede det script, du finder nedenfor.


@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

for /F "tokens=*" \%\%a in ('more') do (
 set full=\%\%a
 set /p prefix=!full:~-7!
 if \%prefix\% == "invalid" (type \%\%a result.xml) else (echo "valid file")
)


Nu for at være specifik på mit spørgsmål først får jeg fejlen


(type was unexpected at this time.


Så hvis jeg fjerner if-grenen og erstatter den med echo \%prefix\% får jeg denne output:


- validECHO is off.
- validECHO is off.
- validECHO is off.
- validECHO is off.
invalidECHO is off.


Kan du venligst hjælpe mig med at oprette en fil, der vil tilføje xml filen til min resultatfil og slippe af med ECHO er slukket? Hvis du tænder @ECHO off, fortsætter du med at udskrive selve koden på skærmen.


Tak for din hjælp !


Alex

Bedste reference


jeb har diagnosticeret og løst dit problem i sine kommentarer (så længe du ændrer >result.xml til >>result.xml). Svaret fra Alex K. er godt, men det virker kun, hvis du kan garantere, at filnavnet ikke indeholder mellemrum.


Men der er en meget enklere og hurtigere løsning: Brug FINDSTR til at filtrere resultaterne af 'xml.exe', kun bevare linjer, der slutter med 'ugyldige'. Jeg synes, det er ikke en god idé at navngive din output-fil result.xml, fordi indholdet ikke er xml-format. Jeg omdøb output filen til 'invalidXML.txt'.


xml val *.xml | findstr /e "invalid" >invalidXML.txt


Ovenstående antager 'xml.exe' producerer gyldige Windows stil linjer, der opsiges med <CR><LF>. Hvis dette ikke er tilfældet, og 'xml.exe' producerer Unix-stil linjer afsluttet med <Lf>, skal du bruge MERE til at konvertere til Windows-stil.


xml val *.xml | more | findstr /e "invalid" >invalidXML.txt


For at få en liste over gyldige filer, du kan bruge (tilføj igen MERE om nødvendigt)


xml val *.xml | findstr /e "- valid" >validXML.txt


Ovenstående bevarer indikatoren '- ugyldig' eller '- gyldig' i slutningen af ​​hver linje, ligesom din oprindelige kode (en gang debugged). Og det virker uden at have brug for en batch-fil :)


Hvis du vil have output som Alex K. foreslog (kun filnavne), så er du tilbage til at bruge en FOR-loop, bedst inden for en batchfil. Jeg migrerede validering af xml.exe til FOR-sløjfen. Du kan vende tilbage til piping resultaterne i partiet, hvis du vil. Denne løsning vil fungere, selvom der er mellemrum i filnavnet. Jeg brugte EOL=: bare hvis et filnavn starter med ;, meget usandsynligt, men muligt.


@echo off
setlocal enableDelayedExpansion
for /f "eol=: delims=" \%\%A in ('xml val *.xml') do (
  set "ln=\%\%A"
  if "!ln:~-7!" == "invalid" (>>invalidXML.txt echo !ln:0,~-10!) else echo !ln:0,~-8! is valid
)


Hvis et filnavn indeholder !, vil navnet blive ødelagt af set "ln=\%\%A" på grund af forsinket ekspansion. Løsningen er at skifte forsinket ekspansion til og fra inden for sløjfen


@echo off
setlocal disableDelayedExpansion
for /f "eol=: delims=" \%\%A in ('xml val *.xml') do (
  set "ln=\%\%A"
  setlocal enableDelayedExpansion
  if "!ln:~-7!" == "invalid" (>>invalidXML.txt echo !ln:0,~-10!) else echo !ln:0,~-8! is valid
  end local
)

Andre referencer 1


Som mønstrene er 'FILENAME - RESULT' kan du bruge FOR sløjfen til at splitte på et hvidt rum sådan at \%\%a=FILENAME, \%\%B=- og \%\%C=RESULT


for /F "tokens=1,2,3 delims= " \%\%a in ('more') do (
    if "\%\%c" neq "valid" (
        echo \%\%a is invalid [\%\%c]
        echo \%\%a >> result.xml
    ) else (
        echo \%\%a is valid
    )
)


Ikke sikker på type \%\%a result.xml, jeg tror ikke, at der er en gyldig kommando.


echo \%\%a >> result.xml vil tilføje filnavnet til result.xml