(Các) lệnh hàng loạt của Windows để đọc dòng đầu tiên từ tệp văn bản


84

Làm cách nào để tôi có thể đọc dòng đầu tiên từ tệp văn bản bằng tệp loạt Windows? Vì tệp lớn nên tôi chỉ muốn xử lý dòng đầu tiên.


1
Hãy thử tiện ích "đầu" GNU32. Đừng nghĩ rằng những gì bạn đang theo đuổi sẽ dễ dàng hoàn thành chỉ với DOS Batch.
Nasir

@Nasir, Không thể thực hiện bằng lệnh có sẵn?
Prajwal Dhatwalia,

Câu trả lời:


48

Đây là một tệp hàng loạt có mục đích chung để in các ndòng trên cùng từ một tệp như headtiện ích GNU , thay vì chỉ một dòng.

@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

Ví dụ:

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

Nó hiện không đếm dòng trống. Nó cũng phải tuân theo giới hạn độ dài dòng của tệp loạt là 8 KB.


10
FYI: "GOTO: EOF" Đó là một nhãn đặc biệt sẽ thoát khỏi tập lệnh mà không cần phải xác định nhãn ": thoát" đặc biệt. Nó cũng hữu ích khi xác định các chương trình con trong lô (những gì mà bạn nói chương trình con Yep?)
Steven

4
Điều này dường như làm hỏng các tệp văn bản vài GB của tôi ... Trên một tệp, nó đã cho tôi lỗi "Hết bộ nhớ" khi cố gắng trả lại 10 dòng, trên tệp khác, nó chỉ trả lại một dòng trống duy nhất khi yêu cầu trả lại. 10 dòng. có ai biết tại sao việc này lại xảy ra?
Dan

1
@Dan - Các dòng dài bao nhiêu? FOR / F "bỏ qua" các dòng dài hơn 8191 byte. Nhưng tôi tự hỏi nếu lỗi "Out of Memory" có phát sinh nếu nó gặp phải một dòng thực sự dài hay không.
dbenham

@StephanMuller - Xem nhận xét của tôi với Dan ở trên
dbenham

Như đã viết, câu trả lời này sẽ bỏ qua các dòng trống. Nó cũng sẽ bỏ qua các dòng bắt đầu bằng dấu chấm phẩy ;, ký tự FOR / F EOL mặc định. Nếu yêu cầu 10 dòng, thì nó sẽ in ra 10 dòng đầu tiên không trống và không bắt đầu bằng ;.
dbenham

224

uh? imo cái này đơn giản hơn nhiều

  set /p texte=< file.txt  
  echo %texte%

16
+1, Điều này là tốt nhất khi nó hoạt động :-) Nó có các giới hạn sau 1) Độ dài dòng tối đa là 1021 byte, không bao gồm EOL. 2) Tệp phải sử dụng Windows style EOL của CarriageReturn LineFeed. 3) ký tự điều khiển Trailing sẽ bị tước từ dòng
dbenham

4
Ngoài ra, texte nên được xác định rõ ràng trước khi đọc tệp chỉ trong trường hợp dòng đầu tiên trống.
dbenham

Dưới đây là một số mẹo bổ sung để cắt tỉa chuỗi. echo %texte:~3%Ví dụ: sẽ bỏ qua ba ký tự đầu tiên. Điều đó rất hữu ích khi bạn đang đọc tệp UTF-8 với BOM.
KargWare

22

Uh các bạn ...

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:\>

2
Nếu tập tin đã có hơn 11 dòng nó sẽ in nhiều hơn so với trước, như: 1 :, 11 :, 21 :, vv ...
Cesar Romero

1
Tốt bắt Cesar! Tôi luôn cố gắng tránh những câu trích dẫn vì chúng làm phiền tôi, nhưng trong trường hợp này thì đó là một ý kiến ​​tồi. Để khắc phục, hãy thay đổi findstr "^1:"và nhận được sự ấm áp và bảo vệ của dấu ngoặc kép. Hoặc, nếu bạn khinh dấu ngoặc kép như tôi và muốn sống một cách nguy hiểm, sử dụngfindstr /b 1:
Amit Naidu

4
nếu bạn muốn nó mà không có dấu ngoặc kép và không có tùy chọn / b sau đó chỉ cần thoát khỏi caret: findstr ^^1.
dbenham

Gợi ý tuyệt vời dbenham, thoát trong cmd luôn luôn thoát khỏi tôi. Nhân tiện, vui lòng không sử dụng phương pháp này cho các tệp lớn, nó thực sự đọc toàn bộ tệp và rất kém hiệu quả. Tiêu chí duy nhất của tôi cho giải pháp này là A) Nó phải là một dòng duy nhất B) Nó phải dễ nhớ hoặc tạo lại từ bộ nhớ và kiểu, không phải sao chép-dán C) Không có công cụ bên ngoài. Các set /pgiải pháp được thêm rất nhiều hiệu quả cho các tập tin lớn.
Amit Naidu

2
Ngoài ra, nó còn thêm số dòng vào dòng văn bản mà bạn thực sự muốn! Do đó không quá hữu ích khi bạn chỉ cần văn bản.
Ross Presser

11

Bạn có thể thử cái này:

@echo off

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

chỉnh sửa Hoặc, giả sử bạn có bốn cột dữ liệu và muốn từ hàng thứ 5 trở xuống dưới cùng, hãy thử điều này:

@echo off

for /f "skip=4 tokens=1-4" %%a in (junkl.txt) do (
  echo %%a %%b %%c %%d
)

1
Điều này đã cho tôi manh mối tôi cần nhưng không hoàn toàn đúng. Không chắc quy trình thích hợp là gì nhưng tôi đã kết hợp giải pháp này vào giải pháp cuối cùng. xem stackoverflow.com/questions/130116#130209
Jesse Vogt

2
Vấn đề của giải pháp này là nó phân định trên khoảng trắng thay vì dòng mới và bạn không thể có tên tệp với khoảng trắng. Bạn có thể khắc phục những sự cố này với các tùy chọn dấu cách và usebackq trong vòng lặp for.
indiv 24/09/08

Làm việc cho tôi, nhưng tôi phải thêm "delims="vào để in ra tên thư mục đầy đủ cùng với dấu cách.
GChuf


4

Dựa trên câu trả lời của người khác. Giờ đây, cho phép bạn chỉ định tệp bạn muốn đọc và biến bạn muốn đưa kết quả vào:

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

Điều này có nghĩa là bạn có thể sử dụng ở trên như thế này (giả sử bạn đã gọi nó là getline.bat)

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

3

Một lớp lót, hữu ích cho chuyển hướng stdout với ">":

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

2

Thử đi

@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

1

Vấn đề với các EXIT /Bgiải pháp, khi thực tế hơn bên trong một tệp loạt chỉ là một phần của nó như sau. Không có quá trình xử lý tiếp theo nào trong tệp lô đã nói sau EXIT /B. Thông thường, có nhiều thứ phải làm theo lô hơn là chỉ một nhiệm vụ giới hạn.

Để giải quyết vấn đề đó:

@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

(Tuy nhiên, những nhân vật được gọi là độc dược vẫn sẽ là một vấn đề.)

Tìm hiểu thêm về chủ đề nhận một dòng cụ thể với các lệnh hàng loạt:

Làm cách nào để lấy dòng thứ n, dòng đầu tiên và dòng cuối cùng của tệp văn bản? " Http://www.netikka.net/tsneti/info/tscmd023.htm

[Đã thêm ngày 28 tháng 8 năm 2012] Người ta cũng có thể có:

@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

Bộ / p texte = <file.txt có lẽ là giải pháp tiện lợi nhất đã được trình bày. Trong chủ đề này của @Spaceballs. Nói chung, tôi sẽ viết set / p "texte" = <"file.txt" nhưng điều đó không quan trọng. Lưu ý rằng ngay cả giải pháp này cũng dễ gặp phải các vấn đề về ký tự độc, tức là có thể bị lỗi tùy thuộc vào những gì tệp.txt chứa.
Timo Salmi

1

Để cicle một tập tin ( file1.txt, file1[1].txt, file1[2].txt, vv):

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%

Và nó đang chạy.


Giải thích cho điều này là: set /pyêu cầu thông qua một dấu nhắc; tuy nhiên với chuyển hướng tệp, <nó ngay lập tức nhận được nội dung của tệp tại dấu nhắc; và khi dòng đầu tiên kết thúc bằng một dòng kết thúc, tại thời điểm đó lời nhắc sẽ dừng đọc và do đó chỉ lưu dòng đầu tiên trong biến.
sdbbs

0

Lưu ý, các phương pháp tiếp cận tệp hàng loạt sẽ bị giới hạn ở giới hạn dòng cho bộ xử lý lệnh DOS - hãy xem Giới hạn độ dài dòng lệnh là gì? .

Vì vậy, nếu cố gắng xử lý một tệp có bất kỳ dòng nào nhiều hơn 8192 ký tự, tập lệnh sẽ chỉ bỏ qua chúng vì giá trị không thể được giữ.


0

Cách khác

setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%i in (filename.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))

2
Tôi khuyên bạn CHỈ nên sử dụng tệp .bat như một phương sách cuối cùng. Nếu có thể, hãy luôn cố gắng sử dụng ngôn ngữ kịch bản "thực": Powershell, WSH, Python ... BẤT CỨ ĐIỀU GÌ ngoại trừ các tệp .bat.
paulsm 4

2
Batch không tệ như vậy (khi bạn biết, bạn làm gì; giống với mọi ngôn ngữ khác). hhay: mã của bạn không hoạt động.
Stephan

bởi vì bạn không sử dụng mở rộng bị trì hoãn
Stephan

1
@ paulsm4: Có gì sai với các tệp hàng loạt? Nó hoạt động trên tất cả các phiên bản Windows và có một tính năng độc đáo được gọi là delayexpansion, cho phép điều kỳ diệu xảy ra mà không cần cài đặt phần mềm của bên thứ 3, miễn là bạn hiểu nó. Bạn có biết rằng bạn có thể TCP / IP với DOS và các tệp hàng loạt trước Powershell & dotNet không?
Zimba

0

Đây là một cách giải quyết bằng cách sử dụng powershell:

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

(Bạn cũng có thể dễ dàng đọc một loạt các dòng với powershell (Get-Content file.txt)[0..3])

Nếu bạn cần đặt một biến bên trong tập lệnh lô làm dòng đầu tiên file.txtbạn có thể sử dụng:

for /f "usebackq delims=" %%a in (`powershell ^(Get-Content file.txt^)[0]`) do (set "head=%%a")

Powershell rất chậm
Anic 17

-1

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

In dòng đầu tiên, sau đó đợi người dùng nhấn phím để in dòng tiếp theo. Sau khi in các dòng cần thiết, nhấn Ctrl + C để dừng.

@Ross Presser: Phương pháp này chỉ in các dòng, không thêm số dòng trước.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.