2012-05-15 2 views
5

Ich habe eine Datei file.txt genannt, die enthält:mehrzeilige Textdatei, wie in eine Umgebung setzen variable

 this is line one^
    this is line two^
    this is the last line 

Wie kann ich das in eine env var setzen?

Ich kann dies tun aus einer Batch-Datei: test.bat

set LF=^ 
    [blank line] 
    [blank line] 
    rem two blank lines needed above 
    set multi=Line 1!LF!Line 2!LF!Last line 
    echo !multi! 

diese gibt drei Linien:

 Line 1 
     Line 2 
     Last line 

so wie kann ich datei.txt in envvar in einer Batch-Datei erhalten ?

+0

das Karat ist^wirklich in der Datei, oder ist das ein Platzhalter für einen CRLF? Ich nehme an, das ist eine Windows-Maschine. – RobW

+0

Das Caret ist wirklich in der Datei, es ist die Möglichkeit, eine Variable zu erstellen, die ein Zeilenvorschubzeichen enthält. 'set LF = ^' gefolgt von zwei leeren Zeilen – jeb

+0

danke jeb für die Klarstellung –

Antwort

7

Wie Dbenham sagte, kann es auch mit for/f gemacht werden, aber es ist ein bisschen komplizierter.

Die einfache 80% ige Lösung ist

setlocal EnableDelayedExpansion 

set "var=" 
set LF=^ 


rem *** Two empty lines are required for the linefeed 
FOR /F "delims=" %%a in (myFile.txt) do (
    set "var=!var!!LF!%%a" 
) 
echo !var! 

aber es funktioniert nicht mit:
- Wenn eine Zeile leer ist, wird es
übersprungen werden - Wenn eine Zeile beginnt mit ; die EOL-Zeichen
- wenn eine Zeile enthält ! (und Carets)

Aber dann könnte man ein wenig komplexe Lösung

verwenden
@echo off 
SETLOCAL DisableDelayedExpansion 
set "all=" 
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ aux1.txt"`) do (
    set "line=%%a" 
    SETLOCAL EnableDelayedExpansion 
    set "line=!line:#=#S!" 
    set "line=!line:*:=!" 
    for /F "delims=" %%p in ("!all!#L!line!") do (
     ENDLOCAL 
     set "all=%%p" 
    ) 
) 
SETLOCAL EnableDelayedExpansion 
if defined all (
set "all=!all:~2!" 
set ^"all=!all:#L=^ 

!" 
set "all=!all:#S=#!" 
) 
echo !all! 

Was macht der Code?
Zunächst wird die findstr /n ^^ wird jede Zeile mit einer Zeilennummer vorangestellt wird und ein Doppelpunkt, wie

1:My first Line 
2:; beginning with a semicolon 
3: 
4:there was an empty line 

Dies löst das Problem der leeren Linien und auch das Standard-EOL-Zeichen ; kann ignoriert werden.
Um den Inhalt der Zeile zu erhalten, wird der Wert auf eine Variable gesetzt, während die verzögerte Erweiterung deaktiviert ist. Dies löst das Problem mit den Zeichen ! und ^.

Um die Zeilennummer und den Doppelpunkt zu entfernen, wird die verzögerte Erweiterung aktiviert (nein, ein Delim von : kann es nicht lösen).

Dann werden alle durch #S ersetzt, dies wird zuerst durchgeführt, da nach dem Präfix das Entfernen der Zeile leer sein könnte und der Austausch fehlschlagen würde.
Aber warum ich es ersetzen?
Das ist, weil ich nicht die Zeilenvorschübe hier einfügen kann, wie die folgenden FOR/F mit eingebetteter Zeilenvorschübe,
so nur scheitern würde ich Zeilenvorschub Marker (in diesem Fall ich #L verwenden), aber der Inhalt der Datei hinzufügen könnte auch eine #L enthalten, aber durch den Austausch aller durch #S sind alle Marker einzigartig.

Nach der Markierung gibt es das Problem, das verzögerte Expansion mit einem endlocal, zu schließen/deaktivieren, aber dem Inhalt der modifizierten all und line variable zu bewahren.
Dies ist mit der FOR/F-endlocal Trick gemacht, wie die %%p Inhalt hinter der endlocal Barriere transportieren kann.

Dann nach dem Lesen der vollständigen Datei, ich überprüfe, ob die all definiert ist, da es für eine leere Datei leer wäre.
Dann wird der erste Zeilenvorschubmarker#L entfernt, und alle anderen Markierungen werden durch ein echtes Zeilenvorschubzeichen ersetzt.
Dann wird die scharfe sicherer #S wieder auf # zurückgesetzt werden.

Das ist alles, so auch offensichtlich ist diese Lösung ...

+0

+1, begann ich die FOR/F-Route hinunterzugehen, aber dann dachte ich mir: "Warum mache ich all diese Arbeit?" :-) – dbenham

+0

sehr witzig :) aber dann bin ich als kleiner Heuschrecken gekommen, der nur die intracsies von DOS lernen will ... und bin demütig, dass du es dem alten College-Versuch geben würdest ... aber vielen Dank für all deine Arbeit, hier und im Ausland! Ich werde auf dem Weg bleiben –

+0

das ist natürlich brillant! als meine Quelldatei (aux) ist wirklich eine HTML-Datei, die in einen sql-Datensatz eingefügt werden muss (und die Quelle enthält! in der ersten Zeile). Also +2 für diesen aufschlussreichen Code! also jetzt muss ich nur die größe der datei überprüfen, um sicherzustellen, dass es unter der 8 k limit ist, wenn nicht, dann kann ich die! alle aufteilen! in! all1! ! all2 !, etc .. etwa die Hälfte meiner Dateien sind 8k-30K also wahrscheinlich ist max vier oder fünf! alle! Vars. danke für das Teilen –

2

Sie waren fast da. Sie müssen jede Textzeile lesen und dann die Zeile und einen Zeilenvorschub an die Variable anhängen.

FOR/F könnte verwendet werden, aber es spielt nicht gut mit verzögerter Erweiterung, wenn der Inhalt ! Zeichen enthält. Es ist auch umständlich, Leerzeilen zu erhalten und um die EOL-Option zu deaktivieren.

Eine einfachere Lösung ist, SET/P zu verwenden, um die Zeilen zu lesen. Die Grenzen dieser Technik sind:

1) Es trimmt aus jeder Zeile Steuerzeichen zurück

2) Die Datei muss Windows-Standard-Zeilenende von Wagenrücklauf, Zeilenvorschub verwenden. Es funktioniert nicht mit Unix Style Line Feed.

3) Es beschränkt sich auf das Lesen 1023 Bytes pro Zeile (ohne die Zeilenabschluss Zeichen)

Beachten Sie, dass eine Umgebungsvariable nur etwas weniger als 8 KByte Daten aufnehmen kann. Sie können also nur eine sehr kleine Datei mit dieser Technik in eine Variable laden.

@echo off 
setlocal enableDelayedExpansion 
set LF=^ 


:: Two blank lines above needed for definition of LF - do not remove 
set file="test.txt" 
set "var=" 
for /f %%N in ('find /c /v "" ^<%file%') do set lineCnt=%%N 
<%file% (
    for /l %%N in (1 1 %lineCnt%) do (
    set "ln=" 
    set /p "ln=" 
    set "var=!var!!ln!!lf!" 
) 
) 
set var 
+0

Danke Herr Benham! Daran arbeite ich jetzt. –

+0

+1, Da es der einfachste Weg ist und in den meisten Fällen brauchen Sie nicht mehr – jeb

+0

und ich denke, dass ich das Limit mit dieser Datei überschreiten könnte, da meine Datei manchmal 8k überschreiten, so dass ich die eine Datei in zwei analysieren muss oder mehr Variablen..so geht es nach DOSville, wo ich das Unmögliche versuchen werde :) –