テキストファイルから最初の行を読み取るWindowsバッチコマンド


84

Windowsバッチファイルを使用してテキストファイルから最初の行を読み取るにはどうすればよいですか?ファイルが大きいので、最初の行だけを扱いたいと思います。


1
GNU32「ヘッド」ユーティリティを試してください。DOSバッチだけで簡単に達成できるとは思わないでください。
Nasir

@Nasir、組み込みコマンドで実行できませんか?
PrajwalDhatwalia19年

回答:


48

これnは、GNUheadユーティリティのようなファイルから、1行だけでなく、一番上の行を印刷するための汎用バッチファイルです。

@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

現在、空白行はカウントされません。また、8KBのバッチファイルの行の長さの制限も適用されます。


10
参考:「GOTO:EOF」これは、特別な「:exit」ラベルを定義しなくてもスクリプトを終了する特別なラベルです。バッチでサブルーチンを定義するときにも役立ちます(何と言いますか?サブルーチン?うん)
Steven

4
これは私の数GBのテキストファイルで爆破されたようです... 1つのファイルでは10行を返そうとすると「メモリ不足」エラーが発生し、もう1つのファイルでは返されるように要求すると1行の空白行が返されました10行。なぜこれが起こるのか考えはありますか?
ダン

1
@ Dan-線の長さはどれくらいですか?FOR / Fは、8191バイトより長い行を「無視」します。しかし、本当に長い行に遭遇した場合、「メモリ不足」エラーが発生するのではないかと思います。
dbenham 2012

@ StephanMuller-上記のDanへの私のコメントを参照してください
dbenham 2012

書かれているように、この答えは空の行を無視します。また;、デフォルトのFOR / FEOL文字であるセミコロンで始まる行も無視されます。10行を要求すると、空ではなく、で始まらない最初の10行が出力され;ます。
dbenham 2012

224

え?imoこれははるかに簡単です

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

16
+1、これは動作する場合に最適です:-)次の制限があります1)最大行長は1021バイトで、EOLは含まれません。2)ファイルはCarriageReturnLineFeedのWindowsスタイルのEOLを使用する必要があります。3)
末尾の

4
また、1行目が空白の場合に備えて、ファイルを読み取る前にtexteを明示的に未定義にする必要があります。
dbenham 2012

ここでは、文字列をトリミングするためのいくつかの余分なヒントがあります。echo %texte:~3%たとえば、最初の3文字はスキップします。これは、BOMを使用して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
引用符なしで/ bオプションなしで使用したい場合は、キャレットをエスケープしてくださいfindstr ^^1
dbenham 2012

素晴らしいヒントdbenham、cmdでのエスケープは常に私をエスケープします。ちなみに、この方法は大きなファイルには使用しないでください。実際にはファイル全体が読み取られ、非常に非効率的です。このソリューションの唯一の基準は、A)1行である必要がありますB)コピーアンドペーストではなく、メモリとタイプから覚えたり再作成したりするのが簡単である必要がありますC)外部ツールがないこと。このset /pソリューションは、大きなファイルに対してはるかに効率的です。
Amit Naidu

2
また、実際に必要なテキストの行の前に行番号が追加されます。したがって、テキストが必要な場合はあまり役に立ちません。
ロスプレッサー2015

11

あなたはこれを試してみるかもしれません:

@echo off

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

編集 または、4列のデータがあり、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
Jesse Vogt

2
このソリューションの問題は、改行ではなくスペースで区切られ、スペースを含むファイル名を使用できないことです。これらの問題は、forループのdelimsおよびusebackqオプションを使用して修正できます。
indiv 2008

私のために働いたが"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リダイレクトに役立つ1つのライナー:

@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。通常、バッチには1つの限られたタスクよりもはるかに多くのものがあります。

その問題に対処するには:

@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

[2012年8月28日追加]次のこともできます。

@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

セット/ p texte = <file.txtは、おそらく提示された中で最も気の利いたソリューションです。@Spaceballsによるこのスレッドで。一般的に、私はset / p "texte" = <"file.txt"と書きますが、それは重要ではありません。このソリューションでさえ、毒文字の問題が発生しやすいことに注意してください。つまり、file.txtの内容によっては失敗する可能性があります。
ティモサルミ2012

1

(ファイルをcicleするにはfile1.txtfile1[1].txtfile1[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 2018

2
バッチがないこと(あなたが知っているとき、あなたは何をすべきか、;他のすべての言語と同じ)悪いです。hhay:コードが機能していません。
ステファン


1
@ paulsm4:バッチファイルの何が問題になっていますか?これはすべての種類のWindowsで動作し、delayedexpansionと呼ばれる独自の機能を備えているため、理解している限り、サードパーティのソフトウェアをインストールしなくても魔法をかけることができます。PowershellとdotNetよりずっと前にDOSとバッチファイルでTCP / IPができることをご存知ですか?
ジンバ

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:このメソッドは、行番号を付加するのではなく、行のみを印刷します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.