2015-12-14 130 views
0

我想弄清楚這一點,但我認爲我走了。這是我在互聯網上找到的:蝙蝠文件刪除文件中的最後一個字符?

copy /A data.js data.js.new /B > nul 
del data.js 
ren data.js.new data.js 

不知何故,它什麼都沒做。

如何創建一個bat文件來刪除文件中的最後一個字符(該字符是逗號,如果有的話)?

+0

您正在做的只是複製文件,刪除原件,然後將副本重命名爲原始文件名。當然,它什麼都不做! – miken32

+0

哈哈好。那麼這就是我的想法,但這是一個類似問題的答案... http://www.computing.net/answers/programming/delete-last-character-from-text-file/22746.html – richard

+0

很想看到網站說,代碼將刪除逗號作爲文件的最後一個字符。 – Squashman

回答

2

也許比它需要更復雜,但我想避免延遲擴展在您的文件內容中打開感嘆號,同時保留空行。批量不是這類事情的最佳語言。如果我是你,我只是使用PowerShell或JScript和substring(0, data.length - 1)或類似的。

不管怎麼說,這是一個純粹的批量解決方案:

@echo off 
setlocal 

set "file=test.txt" 
set "idx=0" 

for /f "delims=" %%I in ('findstr /n "^" "%file%"') do (
    set /a idx += 1 
    setlocal enabledelayedexpansion 
    for %%x in (!idx!) do endlocal & set "line[%%x]=%%I" 
) 

setlocal enabledelayedexpansion 
for %%I in ("!line[%idx%]!") do endlocal & set "lastline=%%~I" 
set "line[%idx%]=%lastline:~0,-1%" 

setlocal enabledelayedexpansion 
>"%file%" (
    for /L %%I in (1,1,%idx%) do echo(!line[%%I]:*:=! 
) 

這裏有一批片斷濫用PowerShell來完成相同的任務。

>out.txt powershell "$c = (gc test.txt) -join \"`n\"; $c.substring(0, $c.length - 1)" 
move /y out.txt test.txt >NUL 

或者這裏是混合批處理+ JScript解決方案。用.bat擴展名保存。

@if (@CodeSection == @Batch) @then 

@echo off & setlocal 

>out.txt (
    cscript /nologo /e:Jscript "%~f0" < test.txt 
) 

move /y out.txt test.txt >NUL 

goto :EOF 
@end // end batch/begin JScript hybrid chimera 

var data = WSH.StdIn.ReadAll(); 
WSH.StdOut.Write(data.substring(0, data.length - 1)); 
+0

由於我的文件內容爲「::: Label1」,它會失敗,它也會刪除冒號。爲什麼你不用'set'lastline =!line [%ubound%]!「'而不是你的FOR循環? – jeb

+0

@jeb好了,現在它更好地處理冒號。我使用'for'循環,因爲我在避免使用'set'的同時啓用延遲擴展,以避免在數據中打擾感嘆號。我只是在檢索值時使用延遲擴展,而不是在設置它們時使用。那是不是很奇怪?我想我可以使用'call set'來避免使用延遲擴展。 – rojo

+0

切換延遲擴展並不奇怪,它似乎是這裏最好的技術。 – jeb

4
@echo off 
setlocal EnableDelayedExpansion 

rem Count the number of lines, minus one 
for /F %%a in ('find /C /V "" ^< data.js') do set /A lines=%%a-1 

< data.js (

    rem Copy number-1 lines 
    for /L %%i in (1,1,%lines%) do (
     set "line=" 
     set /P "line=" 
     echo(!line! 
    ) 

    rem Process last line 
    set /P "line=" 
    echo(!line:~0,-1! 

) > data.js.new 
move /Y data.js.new data.js 
+0

我對你的解決方案似乎是防彈而感到生氣和印象深刻。 – rojo

+0

@rojo:呃,對於所有與特殊字符管理有關的問題,都要指責'/ F'命令!用'set/P'讀取行並且用!延遲擴展訪問變量永遠不會導致問題,我也認爲切換延遲擴展技術不僅很奇怪,而且速度也很慢,隨着文件大小的增加,你的批處理文件解決方案每次都會變慢,因爲每次更大的環境都會重複執行'setlocal'命令。 – Aacini

+0

我確實同意'set/P '對於大文件比'for/F'更快,並且比'set'更優雅地處理特殊字符,如果我是我的話,我仍然會使用JScript解決方案。 395行,17.5kb文件:我的批處理方法= 110秒。你的批處理方法= 38秒。我的JScript混合方法= 18秒。 – rojo

1

以下批處理文件從文件中刪除​​的最後一個字符。這種方法的優點是,爲了性能,只有一個循環。它背後的想法是走路,雖然文件和輸出各一個的線條,而是通過一個迭代的延遲,因此最後一行可分別在循環後進行處理:

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 
> "data.js.new" (
    for /F "delims=" %%L in (' 
     findstr /N /R "^" "data.js" 
    ') do (
     setlocal EnableDelayedExpansion 
     if defined PREV (
      set "PREV=!PREV:*:=!" 
      echo(!PREV! 
     ) 
     endlocal 
     set "PREV=%%L" 
    ) 
    setlocal EnableDelayedExpansion 
    set "PREV=!PREV:*:=!" 
    if defined PREV (
     echo(!PREV:~,-1! 
    ) 
    endlocal 
) 
endlocal 
> nul move /Y "data.js.new" "data.js" 

for /F循環不會遍歷但通過findstr /N /R "^"的輸出,它返回所有以行號和:爲前綴的行,甚至空行也被賦予前綴,因此沒有行會顯示爲空,以便for /F,否則將忽略此行。爲了檢索循環中的原始行,除去第一個:的所有內容。

延遲環境變量擴展(由setlocal/endlocal;另請參閱set /?)已切換,腳本不會丟失任何特殊字符和/或不會崩潰。

+0

我修好了,重新安排了set/endlocals,並刪除了LINE和Flag變量 – jeb

+0

啊,好主意,@jeb,非常感謝! – aschipfl

+0

即使你不需要它,你是否知道在[SO:使一個環境變量在ENDLOCAL下生存]的set/endlocal作用域問題的解決方案(http://stackoverflow.com/questions/3262287/make-一個環境變量,生存-ENDLOCAL/8257951#8257951)? – jeb