Board logo

标题: [文本处理] 请教批处理如何替换文本末尾最后的几个字符? [打印本页]

作者: sajk1    时间: 2017-1-12 07:49     标题: 请教批处理如何替换文本末尾最后的几个字符?

请教,我想把当前文件夹中“1.txt”的倒数第1个字符改为a、倒数第2个字符改为b,另存为“2.txt”在当前文件夹中,该怎么写批处理?
作者: taofan712    时间: 2017-2-10 16:18

本帖最后由 taofan712 于 2017-2-13 09:41 编辑

放着我来!
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do set num=%%a
  4. for /f "tokens=1* delims=:" %%b in ('findstr /n .* 1.txt') do (
  5. set str=%%c
  6. set /a n+=1
  7. if not "!n!"=="%num%" (
  8. echo;!str!>>2.txt
  9. ) else (
  10. echo;!str:~0,-2!ba>>2.txt )
  11. )
复制代码

作者: taofan712    时间: 2017-3-2 00:37

本帖最后由 taofan712 于 2017-3-2 22:57 编辑

此题应有更简洁的答法,mark一下,明日再战!
再 GNU前辈的指导下,代码可以缩减成这样:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do set "ln=%%a" &set "last=%%b"
  3. (for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do if %%a neq %ln% (echo;%%b) else (echo;!last:~0,-2!ba ))>>2.txt
复制代码

作者: Nsqs    时间: 2017-3-2 11:46

本帖最后由 Nsqs 于 2017-3-2 12:05 编辑
  1. ' 2>nul&cls&type a.txt|cscript -nologo -e:"vbs" "%~0"&pause&exit
  2. read=wsh.stdin.readall
  3. wsh.echo left(read,len(read)-2) & "ba"
复制代码
  1. @echo off
  2. for /f "delims=" %%1 in (a.txt)do (
  3. set /a n+=1
  4. call set #_%%n%%=%%1
  5. )
  6. call set #_%%n%%=%%#_%n%%:~,-2%%ba
  7. for /l %%1 in (1 1 %n%)do call echo %%#_%%1%%
  8. pause
复制代码

作者: pcl_test    时间: 2017-3-2 11:55

  1. //&cls&cscript -nologo -e:jscript "%~f0"<"文本.txt"&pause&exit
  2. WSH.Echo(WSH.StdIn.ReadAll().replace(/[^\r\n]([\r\n]*)[^\r\n][\r\n]*?$/, 'b$1a'))
复制代码

作者: taofan712    时间: 2017-3-2 13:43

本帖最后由 taofan712 于 2017-3-2 13:45 编辑

回复 4# Nsqs

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in ('findstr .* a.txt^|find /v /c ""') do set /a ln=%%a,n=1
  3. echo;%ln%&pause
  4. for /f "tokens=1* delims=:" %%b in ('findstr /n .* a.txt') do set last=%%c
  5. echo;%last%&pause
  6. for /f "tokens=1* delims=:" %%d in ('findstr /n .* a.txt') do (
  7. if %%d neq %ln% (
  8. set line=%%e
  9. echo;!line!
  10. set /a n+=1
  11. ) else (
  12. echo;!last:~0,-2!ba
  13. )
  14. )>>2.txt
复制代码

原以为我能写出更简短代码,没想到比我原答案还更多了几行。。。
作者: Nsqs    时间: 2017-3-2 15:09

回复 6# taofan712


    在批处理中for里面尽量少调用例如findstr外部程序,每次读写都会启动findstr程序,在读取大文本数据用for读会很慢很慢的,代码就会变得不实用了
作者: WHY    时间: 2017-3-2 15:40

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%i in (1.txt) do (
  4.         if defined s echo;!s!
  5.         set "s=%%i"
  6. )
  7. echo;!s:~0,-2!ss
复制代码
不考虑最后一行不够2字符的情况
作者: GNU    时间: 2017-3-2 22:33

  1. sed "$s/..$/ba/" 1.txt > 2.txt
复制代码

作者: GNU    时间: 2017-3-2 22:48

回复 6# taofan712

你这个代码可以这样优化:
1、获取文件行数和获取尾行内容,两个操作可以合并到一个for循环里面。
2、最后一个for循环里面直接输出变量的值,没有必要写成三行:
set line=%%e
echo;!line!
set /a n+=1
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do (
  4.     set "ln=%%a"
  5.     set "last=%%b"
  6. )
  7. (for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do (
  8.     if %%a neq %ln% (
  9.         echo;%%b
  10.     ) else (
  11.         echo;!last:~0,-2!ba
  12.     )
  13. ))>2.txt
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2