Metin dosyasından ilk satırı okumak için Windows toplu komutları


85

Bir Windows toplu iş dosyası kullanarak bir metin dosyasındaki ilk satırı nasıl okuyabilirim? Dosya büyük olduğu için sadece ilk satırla ilgilenmek istiyorum.


1
GNU32 "head" yardımcı programını deneyin. Sadece DOS Batch ile peşinde olduğunuz şeyin kolayca başarılacağını düşünmeyin.
Nasir

@Nasir, dahili bir komutla yapılamaz mı?
Prajwal Dhatwalia

Yanıtlar:


48

Burada , tek bir satır yerine nGNU headyardımcı programı gibi bir dosyadan en üst satırları yazdırmak için genel amaçlı bir toplu iş dosyası var .

@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

Örneğin:

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

Şu anda boş satırları saymıyor. Ayrıca, 8 KB'lik toplu iş dosyası satır uzunluğu kısıtlamasına da tabidir.


11
Bilginize: "GOTO: EOF" Bu, özel bir ": exit" etiketi tanımlamak zorunda kalmadan komut dosyasından çıkacak özel bir etikettir. Toplu işteki alt yordamları tanımlarken de kullanışlıdır (ne diyorsunuz? Alt yordamları mı? Evet)
Steven

4
Bu, birkaç GB metin dosyamda bomba gibi görünüyor ... Bir dosyada 10 satır döndürmeye çalışırken bana "Bellek Yetersiz" hatası verdi, diğer dosyada ise geri dönmesini isterken tek bir boş satır döndürdü 10 satır. Bunun neden olduğu hakkında bir fikriniz var mı?
Dan

1
@Dan - Çizgiler ne kadar uzun? FOR / F, 8191 bayttan uzun satırları "yok sayar". Ancak gerçekten uzun bir çizgiyle karşılaştığında "Bellek Yetersiz" hatasının ortaya çıkıp çıkmadığını merak ediyorum.
dbenham

@StephanMuller - Yukarıdaki Dan'e yaptığım yorumu görün
dbenham

Yazıldığı gibi, bu cevap boş satırları göz ardı edecektir. Ayrıca ;, varsayılan FOR / F EOL karakteri olan noktalı virgülle başlayan satırları da yok sayacaktır . 10 satır istenirse, boş olmayan ve başlamayan ilk 10 satırı yazdıracaktır ;.
dbenham

225

uh? imo bu çok daha basit

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

16
+1, Çalıştığı zaman en iyisi budur :-) Aşağıdaki limitleri vardır 1) EOL hariç maksimum 1021 bayt hat uzunluğu. 2) Dosya, CarriageReturn LineFeed'in Windows stili EOL'sini kullanmalıdır. 3) Sondaki kontrol karakterleri satırdan
çıkarılacak

5
Ayrıca, 1. satırın boş olması durumunda, dosyayı okumadan önce metin açıkça tanımlanmamış olmalıdır.
dbenham

İşte ipi kırpmak için bazı ekstra ipuçları. echo %texte:~3%örneğin ilk üç karakteri atlayacak. Bu, BOM ile bir UTF-8 dosyası okurken faydalıdır.
KargWare

22

Ah siz ...

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
Dosyada 11'den fazla satır varsa, ilk satırdan daha fazla yazdıracaktır, örneğin: 1 :, 11 :, 21 :, vb ...
Cesar Romero

1
İyi yakaladın Cesar! Beni rahatsız ettikleri için her zaman alıntılardan kaçınmaya çalışırım, ama bu durumda kötü bir fikirdi. Düzeltmek, değiştirmek findstr "^1:"ve çift tırnakların sıcaklığını ve korumasını kazanmak için. Ya da benim gibi alıntıları küçümsüyor ve tehlikeli bir şekilde yaşamak istiyorsanız, şunu kullanınfindstr /b 1:
Amit Naidu

4
Eğer tırnak işareti olmadan ve / b seçeneği olmadan istiyorsanız o zaman sadece düzeltme işaretini kaçış: findstr ^^1.
dbenham

Büyük ipucu dbenham, cmd'de kaçış her zaman benden kaçar. Bu arada, lütfen bu yöntemi büyük dosyalar için kullanmayın, aslında tüm dosyayı okur ve çok verimsizdir. Bu çözüm için tek kriterim şunlardı: A) Tek bir satır olmalı B) Kopyala-yapıştır değil, bellekten hatırlanması veya yeniden oluşturulması kolay olmalı C) Harici araç yok. set /pSolüsyon çok daha verimli büyük dosyalar içindir.
Amit Naidu

2
Ayrıca, satır numarasını gerçekten istediğiniz metin satırının başına ekler! Bu nedenle, metne ihtiyaç duyduğunuzda pek kullanışlı değil.
Ross Presser

11

Bunu bir deneyebilirsiniz:

@echo off

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

düzenleme Veya, diyelim ki dört veri sütununuz var ve 5. satırdan aşağıya doğru, şunu deneyin:

@echo off

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

1
Bu bana ihtiyacım olan ipucunu verdi ama tam olarak doğru değildi. Doğru prosedürün ne olduğundan emin değilim ama bu çözümü nihai çözüme dahil ettim. bakın stackoverflow.com/questions/130116#130209
Jesse Vogt

2
Bu çözümün sorunu, satırsonu yerine boşluğu sınırlaması ve boşluklarla bir dosya adına sahip olamamanızdır. Bu sorunları for döngüsündeki sınırlamalar ve usebackq seçenekleriyle düzeltebilirsiniz.
indiv

Benim için çalıştı, ancak "delims="tam klasör adlarını boşluklarla birlikte yazdırmak için eklemem gerekiyordu.
GChuf


4

Biraz diğer insanların cevapları üzerine inşa ediliyor. Şimdi okumak istediğiniz dosyayı ve sonucun yerleştirilmesini istediğiniz değişkeni belirlemenize izin verir:

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

Bu, yukarıdakileri bu şekilde kullanabileceğiniz anlamına gelir (bunu getline.bat olarak adlandırdığınızı varsayarak)

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

3

Tek satırlık, ">" ile standart çıkış yönlendirmesi için kullanışlıdır:

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

2

Bunu dene

@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

2

(Bir dosya Cicle için file1.txt, file1[1].txt, file1[2].txtvs.):

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%

Ve çalışıyor.


Bunun açıklaması şudur: set /pbir komut istemiyle sorar; ancak dosya yeniden yönlendirmesiyle <, komut isteminde dosyanın içeriğini hemen alır; ve ilk satır bir satır ile bittiği için, bu noktada bilgi istemi okumayı durdurur ve böylece değişkendeki ilk satırı depolar.
sdbbs

1

EXIT /BÇözümlerle ilgili sorun , bir toplu iş dosyasının yalnızca bir parçası olarak daha gerçekçi olduğunda aşağıdaki gibidir. Söz konusu toplu iş dosyası içinde EXIT /B. Genellikle toplu işlerde sınırlı bir görevden çok daha fazlası vardır.

Bu sorunu çözmek için:

@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

(Bununla birlikte, sözde zehirli karakterler hala bir sorun olacaktır.)

Toplu komutlarla belirli bir satırı alma konusunda daha fazla bilgi:

Bir metin dosyasının n'inci, ilk ve son satırını nasıl alırım? " Http://www.netikka.net/tsneti/info/tscmd023.htm

[28 Ağustos 2012 Eklendi] Birinde şunlar da olabilir:

@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 muhtemelen sunulan en güzel çözümdür. Bu ileti dizisinde @Spaceballs. Genelde set / p "texte" = <"file.txt" yazardım ama bu noktanın dışında. Bu çözümün bile zehirli karakter sorunlarına eğilimli olduğunu unutmayın, yani file.txt içeriğine bağlı olarak başarısız olabilir.
Timo Salmi

0

Toplu iş dosyası yaklaşımlarının DOS komut işlemcisi için satır sınırıyla sınırlı olacağını unutmayın - bkz . Komut satırı uzunluk sınırı nedir? .

Dolayısıyla, 8192 karakterden fazla satıra sahip bir dosyayı işlemeye çalışıyorsanız , komut dosyası, değer tutulamayacağı için bunları atlayacaktır.


0

Diğer yol

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
Bir .bat dosyasını YALNIZCA son çare olarak kullanmanızı tavsiye ederim. Mümkünse, her zaman "gerçek" bir betik dili kullanmayı deneyin: Powershell, WSH, Python ... HERHANGİ BİR ŞEY hariç .bat dosyaları.
paulsm4

2
Toplu iş o kadar da kötü değil (ne yaptığını bildiğinde; diğer dillerde olduğu gibi). hhay: kodunuz çalışmıyor.
Stephan


1
@ paulsm4: Toplu iş dosyalarında sorun nedir? Windows'un tüm çeşitlerinde çalışır ve gecikmeli genişletme adı verilen benzersiz bir özelliğe sahiptir, anladığınız sürece 3. taraf yazılımları yüklemeden sihrin gerçekleşmesine izin verir. Powershell ve dotNet'ten çok önce DOS ve toplu dosyalar ile TCP / IP yapabileceğinizi biliyor muydunuz?
Zimba

0

İşte kullanarak bir geçici çözüm powershell:

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

(Bir dizi satırı da kolayca okuyabilirsiniz powershell (Get-Content file.txt)[0..3])

Bir toplu iş komut dosyası içinde ilk satırınız olarak bir değişken ayarlamanız gerekiyorsa şunu file.txtkullanabilirsiniz:

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

Powershell çok yavaş
Anic17

-1

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

1. satırı yazdırır, ardından kullanıcının sonraki satırı yazdırmak için bir tuşa basmasını bekler. Gerekli satırları yazdırdıktan sonra durdurmak için Ctrl + C tuşlarına basın.

@Ross Presser: Bu yöntem, başa eklenen satır numaralarını değil, yalnızca satırları yazdırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.