3

複数のファイルの行を同時に反復することは可能ですか? 2 つの異なるファイルの行を結合してファイルを出力する必要があります (さらに単語を追加します)。

私はCMDコマンドを知っています:

FOR %variable IN (set) DO command [command-parameters]

ただし、同時に 2 つのファイルを反復処理する必要がある場合は役に立ちません。より正確には、次のことが必要です。

While the first file is not ended
   line1 <- READ a line from the first file
   line2 <- READ a line from the second file
   WRITE on a third file line1 + line2

dosバッチファイルで以前に説明したことを達成する方法を探しています。ありがとう!

4

4 に答える 4

8

私は 3 つの基本的なテクニックを知っており、そこから多数のハイブリッドを導き出すことができます。

オプション 1 (このオプションは wmz ソリューションに非常に似ています)

FOR /F でファイル 1 を読み取り、2 番目の FOR /F で SKIP オプションを指定してファイル 2 を読み取ります。ファイル 2 は、ファイル 1 のループを中断せずにループを中断できるように、呼び出されたサブルーチンで読み取る必要があります。

制限:

  • 空白行があると、行が同期しなくなります。空白行はスキップ カウントに含まれますが、FOR /F によって読み取られません。
  • デフォルトの EOL オプションのため、 で始まる行;は読み取られません。これは、必要に応じて EOL を改行文字に設定することで解決できます。HOW TO: FOR /F EOF を無効にするか、delim として引用符を使用するを参照してください。
  • 行の最大長は 8191 バイトに制限されています。

このオプションは、CALL と、2 番目のファイルを行ごとに 1 回読み取る必要があるため、低速です。

編集 - 2 番目のファイルが早期に終了した場合でも行を出力するように修正されたコード

@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

set /a cnt=0
set "skip="

>"%out%" (
  for /f "usebackq delims=" %%A in ("%file1%") do (
    set "found="
    call :readFile2
    if not defined found (echo %%A - )
  )
)
type "%out%"
exit /b

:readFile2
for /f "usebackq %skip% delims=" %%B in ("%file2%") do (
  set found=1
  echo %%A - %%B"
  goto :break
)
:break
set /a cnt+=1
set "skip=skip=%cnt%"
exit /b


オプション 2

このオプションは、FINDSTR を使用して各行の先頭に行番号とコロンを付けることで、空白行の問題を解決します。FINDSTR は、ファイル 2 から n 番目の行のみを読み取るために使用されるため、2 番目のループから抜け出す必要はありません。

制限:

  • 先頭のコロンは行から削除されます。この制限は追加のコードで解消できますが、より複雑で遅くなります。
  • 行の最大長は 8191 バイトに制限されています。

このオプションは、オプション 1 よりもさらに遅くなります

編集 - 2 番目のファイルが早期に終了した場合でも行を出力するように修正されたコード

@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

>"%file2%.tmp" findstr /n "^" "%file2%"
>"%out%" (
  for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "%file1%"') do (
    set "found="
    for /f "tokens=1* delims=:" %%a in ('findstr "^%%A:" "%file2%.tmp"') do (
      set found=1
      echo %%B - %%b
    )
    if not defined found (echo %%B - )
  )
)
del "%file2%.tmp"
type "%out%"


オプション 3

SET /P を使用して両方のファイルを読み取ります。SET /P は空白行とファイルの終わりを区別できないため、FIND を使用してファイル 1 の行数を取得します。

このオプションは、多くの制限と複雑さを取り除きますが、独自の制限を導入します。

制限:

  • 行には、Windows スタイルの行末記号<CR><LF>. Unix スタイル<LF>は機能しません。
  • 行は 1021 バイトに制限されています
  • 末尾の制御文字は各行から削除されます。

このオプションは断然最速です。制限が許容できる限り、それが好ましいです。

@echo off
setlocal enableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

for /f %%N in ('type "%file1%"^|find /c /v ""') do set "cnt=%%N"
>"%out%" 9<"%file1%" <"%file2%" (
  for /l %%N in (1 1 %cnt%) do (
    set "ln1="
    set "ln2="
    <&9 set /p "ln1="
    set /p "ln2="
    echo !ln1! - !ln2!
  )
)
type "%out%"
于 2012-08-23T23:05:00.407 に答える
2

そして今、私は配達しなければなりません:-)

@echo off
setlocal disabledelayedexpansion
set count=0
for /f "delims=" %%F in (outer.txt) do (
  set fline=%%F
  call :inner %%count%%
  call echo %%fline%%
  set /a count+=1  

)
goto :eof

:inner
if %1 neq 0 set skipline=skip=%1 
  for /f "%skipline% delims=" %%S  in (inner.txt) do (
    set fline=%%F%%S
    goto :eof
  )

一部のタイプの入力では失敗する場合があることに注意してください。&シェルによって特別に扱われる文字またはその他の文字が行に含まれている場合

于 2012-08-23T18:01:09.733 に答える
0

私は2つの弦のためにこれをしなければなりませんでした(他の人にとっては便利かもしれません)

@echo off
setlocal enableextensions enabledelayedexpansion

set string1=token1,token2,token3
set string2=2ndtoken1,2ndtoken2,2ndtoken3

for %%A in (%string1%) do (
    echo From String1: %%A

    set str2=
    for %%S in (!string2!) do (
        if not defined str2 (
            set str2=%%S

            echo !str2!%>tempfile.txt
            FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 1 )

            REM echo StrLen=!strlength!
            echo From String2: !str2!

            call set string2=%%string2:~!strlength!%%
            REM echo String2: !string2!
        )
    )
)
于 2016-04-13T14:50:25.373 に答える
0

ファイルコンテンツの追加:

echo FOO > foo.txt
echo BAR > bar.txt
type foo.txt > both.txt
echo "Both" >> both.txt
type bar.txt >> both.txt
于 2012-08-23T09:52:14.487 に答える