Windows-Batch-Befehl (e) zum Lesen der ersten Zeile aus der Textdatei

83

Wie kann ich die erste Zeile aus einer Textdatei mit einer Windows-Batchdatei lesen? Da die Datei groß ist, möchte ich mich nur mit der ersten Zeile befassen.

Jesse Vogt
quelle
1
Probieren Sie das Dienstprogramm "head" von GNU32 aus. Denken Sie nicht, dass das, wonach Sie suchen, nur mit DOS Batch leicht zu erreichen ist.
Nasir
@Nasir, kann es nicht mit einem eingebauten Befehl gemacht werden?
Prajwal Dhatwalia

Antworten:

48

Hier ist eine universelle Batch-Datei zum Drucken der obersten nZeilen aus einer Datei wie dem GNU- headDienstprogramm anstelle einer einzelnen Zeile.

@echo off

if [%1] == [] goto usage
if [%2] == [] goto usage

call :print_head %1 %2
goto :eof

REM
REM print_head
REM Prints the first non-blank %1 lines in the file %2.
REM
:print_head
setlocal EnableDelayedExpansion
set /a counter=0

for /f ^"usebackq^ eol^=^

^ delims^=^" %%a in (%2) do (
        if "!counter!"=="%1" goto :eof
        echo %%a
        set /a counter+=1
)

goto :eof

:usage
echo Usage: head.bat COUNT FILENAME

Beispielsweise:

Z:\>head 1 "test file.c"
; this is line 1

Z:\>head 3 "test file.c"
; this is line 1
    this is line 2
line 3 right here

Leerzeilen werden derzeit nicht gezählt. Es unterliegt auch der Beschränkung der Zeilenlänge für Batchdateien von 8 KB.

indiv
quelle
10
Zu Ihrer Information: "GOTO: EOF" Dies ist eine spezielle Bezeichnung, mit der das Skript beendet wird, ohne dass eine spezielle Bezeichnung ": exit" definiert werden muss. Es ist auch nützlich, wenn Sie Unterprogramme im Stapel definieren (was sagen Sie? Unterprogramme? Ja)
Steven
4
Dies scheint sich auf meine mehreren GB-Textdateien auszuwirken ... Bei einer Datei wurde beim Versuch, 10 Zeilen zurückzugeben, der Fehler "Nicht genügend Speicher" angezeigt, bei der anderen Datei wurde nur eine einzige leere Zeile zurückgegeben, wenn ich zur Rückgabe aufgefordert wurde 10 Zeilen. Irgendwelche Ideen, warum das passiert?
Dan
1
@ Dan - Wie lang sind die Zeilen? FOR / F "ignoriert" Zeilen, die länger als 8191 Bytes sind. Aber ich frage mich, ob der Fehler "Out of Memory" auftritt, wenn er auf eine wirklich lange Schlange stößt.
Dbenham
@StephanMuller - Siehe meinen Kommentar zu Dan oben
Dbenham
Wie geschrieben, ignoriert diese Antwort leere Zeilen. Zeilen, die mit einem Semikolon beginnen ;, dem Standardzeichen FOR / F EOL, werden ebenfalls ignoriert . Wenn Sie nach 10 Zeilen fragen, werden die ersten 10 Zeilen gedruckt, die nicht leer sind und nicht mit beginnen ;.
Dbenham
217

äh? imo das ist viel einfacher

  set /p texte=< file.txt  
  echo %texte%
Spaceballs
quelle
16
+1, Dies ist das Beste, wenn es funktioniert :-) Es hat folgende Grenzen 1) Maximale Zeilenlänge von 1021 Bytes, ohne EOL. 2) Die Datei muss die Windows-EOL von CarriageReturn LineFeed verwenden. 3) Nachfolgende Kontrollzeichen werden von der Zeile entfernt
dbenham
4
Außerdem sollte texte vor dem Lesen der Datei explizit undefiniert sein, falls die erste Zeile leer ist.
Dbenham
Hier sind einige zusätzliche Tipps zum Trimmen der Saite. echo %texte:~3%Zum Beispiel werden die ersten drei Zeichen übersprungen. Dies ist nützlich, wenn Sie eine UTF-8-Datei mit Stückliste lesen.
KargWare
22

Äh ihr ...

C:\>findstr /n . c:\boot.ini | findstr ^1:

1:[boot loader]

C:\>findstr /n . c:\boot.ini | findstr ^3:

3:default=multi(0)disk(0)rdisk(0)partition(1)\WINNT

C:\>
Amit Naidu
quelle
2
Wenn die Datei mehr als 11 Zeilen enthält, wird mehr als die erste gedruckt, z. B.: 1:, 11:, 21:, etc ...
Cesar Romero
1
Guter Fang Cesar! Ich versuche immer, Zitate zu vermeiden, weil sie mich nerven, aber in diesem Fall war es eine schlechte Idee. Um dies zu beheben, wechseln Sie zu findstr "^1:"und erhalten Sie die Wärme und den Schutz von doppelten Anführungszeichen. Oder, wenn Sie Zitate wie mich verachten und gefährlich leben wollen, verwenden Siefindstr /b 1:
Amit Naidu
4
Wenn Sie es ohne Anführungszeichen und ohne / b-Option möchten, entkommen Sie einfach dem Caret : findstr ^^1.
Dbenham
Toller Hinweis dbenham, die Flucht in cmd entgeht mir immer. Verwenden Sie diese Methode übrigens nicht für große Dateien, sie liest tatsächlich die gesamte Datei und ist sehr ineffizient. Meine einzigen Kriterien für diese Lösung waren: A) Es sollte eine einzelne Zeile sein. B) Es sollte leicht zu merken oder aus dem Speicher und Typ neu zu erstellen sein, nicht kopieren und einfügen. C) Keine externen Tools. Die set /pLösung ist für große Dateien weitaus effizienter.
Amit Naidu
2
Außerdem wird die Zeilennummer der gewünschten Textzeile vorangestellt! Daher nicht so nützlich, wenn Sie nur den Text brauchten.
Ross Presser
11

Sie könnten dies versuchen:

@echo off

for /f %%a in (sample.txt) do (
  echo %%a
  exit /b
)

Bearbeiten Oder sagen Sie, Sie haben vier Datenspalten und möchten von der 5. Zeile bis zum Ende Folgendes:

@echo off

for /f "skip=4 tokens=1-4" %%a in (junkl.txt) do (
  echo %%a %%b %%c %%d
)
Ross Fuhrman
quelle
1
Dies gab mir den Hinweis, den ich brauchte, war aber nicht ganz richtig. Ich bin mir nicht sicher, wie das richtige Verfahren war, aber ich habe diese Lösung in die endgültige Lösung aufgenommen. siehe stackoverflow.com/questions/130116#130209
Jesse Vogt
2
Das Problem dieser Lösung besteht darin, dass sie durch Leerzeichen anstelle von Zeilenumbrüchen begrenzt wird und Sie keinen Dateinamen mit Leerzeichen haben können. Sie können diese Probleme mit den Optionen delims und usebackq in der for-Schleife beheben.
indiv
Arbeitete für mich, aber ich musste hinzufügen "delims=", um vollständige Ordnernamen zusammen mit Leerzeichen auszudrucken.
GChuf
4

Etwas auf den Antworten anderer Leute aufbauen. Jetzt können Sie die Datei angeben, aus der Sie lesen möchten, und die Variable, in die das Ergebnis eingefügt werden soll:

@echo off
for /f "delims=" %%x in (%2) do (
set %1=%%x
exit /b
)

Dies bedeutet, dass Sie das oben genannte wie folgt verwenden können (vorausgesetzt, Sie haben es getline.bat genannt).

c:\> dir > test-file
c:\> getline variable test-file
c:\> set variable  
variable= Volume in drive C has no label.
Ray Hayes
quelle
3

Ein Liner, nützlich für die Standardumleitung mit ">":

@for /f %%i in ('type yourfile.txt') do @echo %%i & exit
PabloG
quelle
2

Versuche dies

@echo off
setlocal enableextensions enabledelayedexpansion
set firstLine=1
for /f "delims=" %%i in (yourfilename.txt) do (
    if !firstLine!==1 echo %%i
    set firstLine=0
)
endlocal
Sarath Avanavu
quelle
1

Das Problem mit den EXIT /BLösungen, wenn sie realistischer in einer Batch-Datei als nur ein Teil davon sind, ist das folgende. Es erfolgt keine nachfolgende Verarbeitung innerhalb der Batch-Datei nach dem EXIT /B. Normalerweise gibt es bei Chargen viel mehr als nur eine begrenzte Aufgabe.

Um diesem Problem entgegenzuwirken:

@echo off & setlocal enableextensions enabledelayedexpansion
set myfile_=C:\_D\TEST\My test file.txt
set FirstLine=
for /f "delims=" %%i in ('type "%myfile_%"') do (
  if not defined FirstLine set FirstLine=%%i)
echo FirstLine=%FirstLine%
endlocal & goto :EOF

(Die sogenannten Giftcharaktere werden jedoch immer noch ein Problem sein.)

Weitere Informationen zum Abrufen einer bestimmten Zeile mit Batch-Befehlen:

Wie erhalte ich die n-te, die erste und die letzte Zeile einer Textdatei? " Http://www.netikka.net/tsneti/info/tscmd023.htm

[Hinzugefügt am 28.08.2012] Man kann auch haben:

@echo off & setlocal enableextensions
set myfile_=C:\_D\TEST\My test file.txt
for /f "tokens=* delims=" %%a in (
  'type "%myfile_%"') do (
    set FirstLine=%%a& goto _ExitForLoop)
:_ExitForLoop
echo FirstLine=%FirstLine%
endlocal & goto :EOF
Timo Salmi
quelle
Das set / p texte = <file.txt ist wahrscheinlich die geschickteste Lösung, die vorgestellt wurde. In diesem Thread von @Spaceballs. Im Allgemeinen würde ich set / p "texte" = <"file.txt" schreiben, aber das ist nebensächlich. Beachten Sie, dass auch diese Lösung anfällig für Probleme mit Giftcharakteren ist, dh je nachdem, was die Datei file.txt enthält, kann dies fehlschlagen.
Timo Salmi
1

Um Ciclo eine Datei ( file1.txt, file1[1].txt, file1[2].txt, usw.):

START/WAIT C:\LAERCIO\DELPHI\CICLADOR\dprCiclador.exe C:\LAERCIUM\Ciclavel.txt

rem set/p ciclo=< C:\LAERCIUM\Ciclavel.txt:
set/p ciclo=< C:\LAERCIUM\Ciclavel.txt

rem echo %ciclo%:
echo %ciclo%

Und es läuft.

Laercio
quelle
Die Erklärung dafür ist: set /pfragt durch eine Eingabeaufforderung; <Bei der Dateiumleitung wird der Inhalt der Datei jedoch sofort an der Eingabeaufforderung abgerufen. und da die erste Zeile mit einem Zeilenende endet, hört die Eingabeaufforderung an diesem Punkt auf zu lesen und speichert somit nur die erste Zeile in der Variablen.
SDBBS
0

Beachten Sie, dass die Ansätze für Batchdateien auf das Zeilenlimit für den DOS-Befehlsprozessor beschränkt sind - siehe Was ist das Limit für die Befehlszeilenlänge ? .

Wenn Sie also versuchen, eine Datei mit mehr als 8192 Zeichen zu verarbeiten, überspringt das Skript diese einfach, da der Wert nicht gespeichert werden kann.

Kevinjansz
quelle
0

Ein anderer Weg

setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%i in (filename.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))
hhay
quelle
2
Ich würde empfehlen, NUR eine .bat-Datei als letzten Ausweg zu verwenden. Wenn alles möglich ist, versuchen Sie immer, eine "echte" Skriptsprache zu verwenden: Powershell, WSH, Python ... ALLES außer .bat-Dateien.
Pauls4
2
Batch ist nicht so schlecht (wenn Sie wissen, was Sie tun; wie bei jeder anderen Sprache). hhay: dein code funktioniert nicht.
Stephan
weil Sie keine verzögerte Erweiterung verwenden
Stephan
1
@ paulsm4: Was ist los mit Batch-Dateien? Es funktioniert unter allen Windows-Varianten und verfügt über eine einzigartige Funktion namens delayedexpansion, mit der Magie ohne Installation von Software von Drittanbietern ausgeführt werden kann, sofern Sie dies verstehen. Wussten Sie, dass Sie TCP / IP mit DOS- und Batch-Dateien lange vor Powershell & dotNet ausführen können?
Zimba
0

Hier ist eine Problemumgehung mit powershell:

powershell (Get-Content file.txt)[0]

(Sie können auch leicht eine Reihe von Zeilen mit lesen powershell (Get-Content file.txt)[0..3])

Wenn Sie eine Variable in einem Batch-Skript als erste Zeile festlegen müssen, file.txtkönnen Sie Folgendes verwenden:

for /f "usebackq delims=" %%a in (`powershell ^(Get-Content file.txt^)[0]`) do (set "head=%%a")
mmj
quelle
Powershell ist sehr langsam
Anic17
-1

for /f "delims=" %a in (downing.txt) do echo %a & pause>nul

Druckt die erste Zeile und wartet darauf, dass der Benutzer eine Taste drückt, um die nächste Zeile zu drucken. Drücken Sie nach dem Drucken der erforderlichen Zeilen Strg + C, um den Vorgang zu beenden.

@ Ross Presser: Diese Methode druckt nur Zeilen, keine Zeilennummern.

Zimba
quelle