Пакетні команди Windows для читання першого рядка з текстового файлу


84

Як я можу прочитати перший рядок із текстового файлу за допомогою командного файлу Windows? Оскільки файл великий, я хочу мати справу лише з першим рядком.


1
Спробуйте утиліту GNU32 "head". Не думайте, що вам слід просто зробити DOS Batch.
Насір

@Nasir, чи не можна це зробити за допомогою вбудованої команди?
Праджвал Датхалія,

Відповіді:


48

Ось пакетний файл загального призначення для друку верхніх nрядків із такого файлу, як headутиліта GNU , замість одного рядка.

@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

Наприклад:

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

Наразі порожні рядки не враховуються. Також на нього поширюється обмеження довжини рядка пакетного файлу на 8 КБ.


10
FYI: "GOTO: EOF" Це спеціальна мітка, яка виходить із сценарію без необхідності визначати спеціальну мітку ": exit". Це також корисно при визначенні підпрограм у пакеті (що ви кажете? Підпрограми? Так)
Стівен

4
Здається, це бомбардує кілька моїх текстових файлів ГБ ... В одному файлі при спробі повернути 10 рядків у мене з'явилася помилка "Немає пам’яті", в іншому файлі він просто повернув один порожній рядок на прохання повернути 10 рядків. Будь-які ідеї, чому це відбувається?
Dan

1
@Dan - Скільки довгих рядків? FOR / F "ігнорує" рядки довжиною більше 8191 байт. Але мені цікаво, чи не виникає помилка "Немає пам’яті", якщо вона зустрічає справді довгу чергу.
dbenham

@StephanMuller - Див. Мій коментар до Дана вище
dbenham,

Як написано, ця відповідь ігноруватиме порожні рядки. Він також ігноруватиме рядки, які починаються крапкою з комою ;, символом FOR / F EOL за замовчуванням. Якщо ви запитуєте 10 рядків, тоді буде надруковано перші 10 рядків, які не є порожніми і не починаються з ;.
dbenham

224

а? imo це набагато простіше

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

16
+1, це найкраще, коли воно працює :-) Він має такі обмеження: 1) Максимальна довжина рядка 1021 байт, не враховуючи EOL. 2) Файл повинен використовувати EOL стилю Windows із CarriageReturn LineFeed. 3) Кінцеві контрольні символи будуть вилучені з рядка
dbenham,

4
Крім того, текстовий текст повинен бути чітко невизначений перед читанням файлу на випадок, якщо 1-й рядок порожній.
dbenham

Ось кілька додаткових порад щодо обрізання струни. echo %texte:~3%наприклад, пропустить перші три символи. Це корисно, коли ви читаєте файл UTF-8 із специфікацією.
KargWare

22

Ух, хлопці ...

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
Якщо файл має більше 11 рядків, він надрукує більше, ніж перший, наприклад: 1 :, 11 :, 21 :, тощо ...
Cesar Romero

1
Хороший улов Сезар! Я завжди намагаюся уникати цитат, бо вони мене дратують, але в цьому випадку це була погана ідея. Щоб виправити, змінити findstr "^1:"та отримати тепло і захист подвійних лапок. Або, якщо ви зневажаєте цитати, подібні до мене, і хочете жити небезпечно, використовуйтеfindstr /b 1:
Аміт Найду

4
якщо ви хочете без лапок і без опції / б , то просто уникнути каретки: findstr ^^1.
dbenham

Чудовий натяк dbenham, втікання в cmd завжди уникає мене. До речі, не використовуйте цей метод для великих файлів, він насправді читає весь файл і дуже неефективний. Моїм єдиним критерієм для цього рішення були A) Це повинен бути один рядок B) Це повинно бути легко запам'ятовувати або відтворювати з пам'яті та типу, а не копіювати-вставляти C) Відсутність зовнішніх інструментів. set /pРішення є набагато більш ефективним для великих файлів.
Аміт Найду

2
Крім того, він додає номер рядка до рядка тексту, який ви насправді хочете! Тому не такий корисний, коли вам просто потрібен був текст.
Росс Прессер,

11

Ви можете спробувати:

@echo off

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

редагувати Або, скажімо, у вас є чотири стовпці даних і ви хочете, щоб з 5-го рядка вниз до кінця, спробуйте це:

@echo off

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

1
Це дало мені підказку, яка мені потрібна, але була не зовсім правильною. Не знаю, яка була правильна процедура, але я включив це рішення в остаточне рішення. див. stackoverflow.com/questions/130116#130209
Джессі Фогт

2
Проблема цього рішення полягає в тому, що він розмежовує пробіл замість нового рядка, і ви не можете мати ім'я файлу з пробілами. Ви можете виправити ці проблеми за допомогою роздільників та опцій usebackq у циклі for.
indiv

Працював у мене, але мені довелося додати, "delims="щоб роздрукувати повні назви папок разом із пробілами.
GChuf


4

Трохи спираючись на відповіді інших людей. Тепер ви можете вказати файл, з якого ви хочете прочитати, і змінну, в яку потрібно ввести результат:

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

Це означає, що ви можете використовувати вищезазначене так (якщо припустити, що ви назвали це getline.bat)

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

3

Один вкладиш, корисний для перенаправлення stdout з ">":

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

2

Спробуйте це

@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

Проблема з EXIT /Bрішеннями, коли більш реально всередині пакетного файлу, як лише однієї його частини, полягає в наступному. Після зазначеного пакетного файлу після EXIT /B. Зазвичай партій набагато більше, ніж лише одне, обмежене завдання.

Щоб вирішити цю проблему:

@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

(Однак так звані символи отрути все одно будуть проблемою.)

Детальніше на тему отримання певного рядка з командними командами:

Як отримати n-ий, перший і останній рядки текстового файлу? " Http://www.netikka.net/tsneti/info/tscmd023.htm

[Додано 28 серпня 2012 р.] Також можна мати:

@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

Set / p texte = <file.txt - це, мабуть, найдобріше рішення, яке було представлено. У цій темі від @Spaceballs. Взагалі, я б написав set / p "texte" = <"file.txt", але це поруч. Зверніть увагу, що навіть це рішення схильне до проблем з отруйними символами, тобто може вийти з ладу залежно від того, що містить файл.
Timo Salmi

1

Щоб Cicle файл ( file1.txt, file1[1].txt, file1[2].txtі т.д.):

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%

І це працює.


Пояснення цьому: set /pзапитує через підказку; однак при перенаправленні файлу <воно негайно отримує вміст файлу за запитом; і оскільки перший рядок закінчується рядком, що закінчується, в цей момент підказка припиняє читання і, таким чином, зберігає лише перший рядок у змінній.
sdbbs

0

Зауважте, підходи до командного файлу будуть обмежені обмеженням рядків для командного процесора DOS - див. Що таке обмеження довжини командного рядка? .

Отже, якщо ви намагаєтесь обробити файл, який має будь-який рядок більше 8192 символів, скрипт просто пропустить їх, оскільки значення не може бути збережене.


0

Інший спосіб

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
Я б рекомендував використовувати файл .bat ТІЛЬКИ в крайньому випадку. Якщо це можливо, завжди намагайтеся використовувати "справжню" мову сценаріїв: Powershell, WSH, Python ... БУДЬ-ЩО, але файли .bat.
paulsm4,

2
Партія не така вже й погана (коли ти знаєш, чим ти займаєшся, як і з будь-якою іншою мовою). hhay: ваш код не працює.
Stephan

тому що ви не використовуєте відкладене розширення
Стефан,

1
@ paulsm4: Що не так із пакетними файлами? Він працює на всі смаки Windows і має унікальну функцію, яка називається delayedexpansion, дозволяючи чарівництво відбуватися без установки стороннього програмного забезпечення, якщо ви це розумієте. Чи знали ви, що можете TCP / IP з DOS і пакетними файлами задовго до Powershell і dotNet?
Зімба

0

Ось обхідний шлях із використанням powershell:

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

(Ви також можете легко прочитати ряд рядків з powershell (Get-Content file.txt)[0..3] )

Якщо вам потрібно встановити змінну всередині пакетного сценарію, як перший рядок file.txtви можете використовувати:

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

Powershell дуже повільний
Anic17

-1

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

Друкує 1-й рядок, а потім чекає, поки користувач натисне клавішу, щоб надрукувати наступний рядок. Після друку необхідних рядків натисніть Ctrl + C, щоб зупинити.

@Ross Presser: Цей метод друкує лише рядки, а не додає номери рядків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.