2012-10-25 51 views
1

我發現了一個以前的帖子,它提供了這個答案的一部分,用每個文件的最後一行創建新文件在目錄中,如下圖所示:批量將幾個.txt文件的最後一行復制到一個新的.txt文件中,並在新行上附加文件名

@echo off 
for %%f in (*.log) do (
    set /a line_count = -1 
    for /f %%l in (%%f) do set /a line_count += 1 
    more +%line_count% %%f 
) 

如果你的文件不以換行符結束,你就必須在LINE_COUNT變量初始化爲0,而不是-1。

您可將更多的輸出結果附加到文件:

more +%line_count% %%f >> your_results_file 

我需要什麼,現在幫助是找出一種方法來追加.txt文件的文件名最後一行是從新文件中的行中取出,因此它將作爲目錄中每個文件的文件名最後一行。

這是任何人都可以提供幫助的東西嗎?謝謝。

+0

你有沒有考慮過使用PowerShell?這在PowerShell中很簡單。 – David

回答

0

你可以

@echo off 
setlocal enabledelayedexpansion 
for %%f in (*.log) do (
    set /a line_count = -1 
    for /f "tokens=*" %%l in (%%f) do (
     set /a line_count += 1 
     set value=%%l 
     set file=%%f 
    ) 
    echo line_count=%line_count% value=!value! file=!file! 
) 
0

天啊 - 不要使用FOR循環在文件計數線 - 這是緩慢和不可靠的。它將跳過空行,也可以跳過以EOL字符開頭的行,除非禁用EOL。使用FIND /C來計算行數。帶有/V選項的空搜索字符串將匹配所有行。

使用SET/P打印文件的名稱而不發出換行符。

@echo off 
setlocal enableDelayedExpansion 
>output.txt (
    for %%F in (*.log) do (
    <nul set /p "=%%F: " 
    for /f %%N in ('type "%%F"^|find /c /v ""') do set /a skip=%%N 
    if !skip! gtr 0 set /a skip-=1 
    more +!skip! "%%F" 
) 
) 

如果有任何文件名包含!然後延遲擴展必須開啓和關閉

@echo off 
setlocal disableDelayedExpansion 
>output.txt (
    for %%F in (*.bat) do (
    set "file=%%F" 
    setlocal enableDelayedExpansion 
    <nul set /p "=!file!: " 
    for /f %%N in ('type "!file!"^|find /c /v ""') do set /a skip=%%N 
    if !skip! gtr 0 set /a skip-=1 
    more +!skip! "!file!" 
    endlocal 
) 
) 
type output.txt 
0

我的兩個例子切換不文本文件的最後幾行復制到另一個文件,但它可以被用來這樣做。

我的示例反而像Linux命令TAIL一樣工作,並顯示最後幾行。

經過一番實驗,我發現以下是顯示文件最後幾行的最快方法。當然,缺點是FOR會跳過空行。

TAIL.BAT

@echo off 
setlocal enabledelayedexpansion 
set "fn=%~1" 
set "fn=%fn:(=^(%" 
set "fn=%fn:)=^)%" 
if "%~2"=="" set count=1 
if "%~2" neq "" set count=%~2 
(
    for /f "tokens=3" %%x in ('find /c /v "" %fn%') do set count=%%x 
    set /a count=!count!-%count% 
) 
echo. 
for /f "skip=%count% tokens=*" %%x in (%fn%) do echo %%x 

%1是文件名
%2被線顯示的選項號。如果留空,則TAIL.BAT顯示最後一行。


要確定其中兩種方法都是快,FOR,或MORE方法,我創建了下面的(與很多的話)。我將它包含在內,以便您可以自己測試它。

注意,這個例子中的最大部分是經過時間的計算:

TESTTAIL.BAT

@echo off 
:: 
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
:: 
:: TAIL.BAT filename [linesToShow [/v]] 
:: 
:: LINESTOSHOW = Number of lines at the end of the file 
::    to display. If this is left blank TAIL 
::    assumes that you only want the last line 
:: 
:: /v   = Show the math, must be used with LINESTOSHOW 
::    Without this switch, the time to complete 
::    will be displayed, but not the math. 
:: 

setlocal enabledelayedexpansion 
set "fn=%~1"     & :: Get File Name 
set "fn=%fn:(=^(%"    & :: Escape Left Brackets 
set "fn=%fn:)=^)%"    & :: Escape Right Brackets 
if "%~2"=="" set count=1 & :: Assume Last Line 
if "%~2" neq "" set count=%~2 & :: Specify # of Lines to show 

(:: Count Lines in File 
    for /f "tokens=3" %%x in ('find /c /v "" %fn%') do set count=%%x 
    :: Subtract # to skip from lines in file 
    set /a count=!count!-%count% 
) 

:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
:: :: Get last %Count% lines of file using MORE+ :: :: 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
echo. 
set start=%time%    & :: Get Start Time 
more +%count% %fn%    & :: Show the last %count% lines 
set end=%time%     & :: Get End Time 

call :Elapsed %end% %start% %3 & :: Calculate Time Elapsed 

:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
:: :: Get last %Count% lines of file using FOR :: :: 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
set start=%time%    & :: Get Start Time 
for /f "skip=%count% tokens=*" %%x in (%fn%) do echo %%x 
set end=%time%     & :: Get End Time 

call :Elapsed %end% %start% %3 & :: Calculate Time Elapsed 

endlocal 
goto :eof 

:Elapsed 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
::    Calculate Elapsed Time    :: 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
echo. 
if "%3"=="/v" ECHO  Start : %1 
if "%3"=="/v" ECHO  End : -%2 
if "%3"=="/v" ECHO    ============= 

for /f "tokens=1-8 delims=:.%tab% " %%a in ("%1 %2") do (
    set "hh= %%a - %%e " 
    set "mm= %%b - %%f " 
    set "ss= %%c - %%g " 
    set "ms= %%d - %%h " 
) 

set "hh=%hh: 0=%" 
set /a hh=%hh% 
set "mm=%mm: 0=%" 
set /a mm=%mm% 
set "ss=%ss: 0=%" 
set /a ss=%ss% 
set "ms=%ms: 0=%" 
set /a ms=%ms% 

if %ms% lss 0 (
    set /a ms=100+%ms% 
    set /a ss-=1 
) 
if %ss% lss 0 (
    set /a ss=60+%ss% 
    set /a mm-=1 
) 
if %mm% lss 0 (
    set /a mm=60+%mm% 
    set /a hh-=1 
) 
if %hh% lss 0 set /a hh=24+%hh% 

if %hh% lss 10 set hh=0%hh% 
if %mm% lss 10 set mm=0%mm% 
if %ss% lss 10 set ss=0%ss% 
if %ms% lss 10 set ms=0%ms% 

echo Completed in : %hh%:%mm%:%ss%.%ms% 
echo. 

goto :eof 

這裏是我的機器上運行上面的示例代碼,請注意我指定的最後5行:

D:\Misc>testtail 2012-10-25(9).MIME 5 /v 

MDAwMDAgbg0KMDAwMDA5NTQwOCAwMDAwMCBuDQp0cmFpbGVyDQo8PA0KL1NpemUgMzUNCi9Sb290 
IDMzIDAgUg0KL0luZm8gMzAgMCBSDQovSUQgWzwxM0NBMjNBRjhFMTk2RkEyOTRGMThFM0I3QTJC 
QkNFNj48N0I5OUE4NTkxOEE1MzgzQjY3NTY5OUMxNkFEQTA3RUQ+XQ0KPj4NCnN0YXJ0eHJlZg0K 
OTcyNDMNCiUlRU9GDQo= 
---915665055-1601124504-1351078287=:50774-- 

     Start : 15:30:57.11 
     End : -15:30:56.96 
       ============= 
Completed in : 00:00:00.15 

MDAwMDAgbg0KMDAwMDA5NTQwOCAwMDAwMCBuDQp0cmFpbGVyDQo8PA0KL1NpemUgMzUNCi9Sb290 
IDMzIDAgUg0KL0luZm8gMzAgMCBSDQovSUQgWzwxM0NBMjNBRjhFMTk2RkEyOTRGMThFM0I3QTJC 
QkNFNj48N0I5OUE4NTkxOEE1MzgzQjY3NTY5OUMxNkFEQTA3RUQ+XQ0KPj4NCnN0YXJ0eHJlZg0K 
OTcyNDMNCiUlRU9GDQo= 
---915665055-1601124504-1351078287=:50774-- 

     Start : 15:30:57.16 
     End : -15:30:57.15 
       ============= 
Completed in : 00:00:00.01 


D:\Misc> 

正如你所看到的,在這兩個之間有很大的速度差,與FOR方法大大faste r比MORE

相關問題