Board logo

标题: [文本处理] 批处理如何删除每行最后一个指定字符之前的内容/提取每行最后一个指定字符之后的内容 [打印本页]

作者: lyfwcn    时间: 2015-1-28 20:51     标题: 批处理如何删除每行最后一个指定字符之前的内容/提取每行最后一个指定字符之后的内容

本帖最后由 pcl_test 于 2016-10-14 14:22 编辑

http://www.bathome.net/post.php?action=newthread&fid=5                              (这有三个/)
http://www.bathome.net/c/3553908420                                                               (这有四个/)

删除/前的
变成
post.php?action=newthread&fid=5
3553908420

谢谢
作者: yiwuyun    时间: 2015-1-28 21:06

  1. sed "s/.*\///" 1.txt
复制代码

作者: apang    时间: 2015-1-28 22:40

  1. @echo off
  2. for /f "delims=" %%a in (a.txt) do echo %%~nxa
  3. pause
复制代码

作者: lyfwcn    时间: 2015-1-29 04:38

本帖最后由 lyfwcn 于 2015-1-29 09:53 编辑

回复 3# apang

谢谢,可行.但换了个符号就不行了
作者: lyfwcn    时间: 2015-1-29 04:39

yiwuyun 发表于 2015-1-28 21:06

我下了个sed,文本改成1.txt,结果没变化。
作者: yiwuyun    时间: 2015-1-29 12:21

  1. sed -i.txt "s/.*\///" 1.txt
复制代码
  1. @echo off
  2. for /f "delims=" %%a in ('type 1.txt') do (
  3.   set line=%%a
  4.   setlocal EnableDelayedExpansion
  5.   set "line=!line:/= !"
  6.   call :Dispose "^!line^!"
  7.   endlocal
  8. )
  9. exit /b 0
  10. :Dispose
  11. set "line=%~1"
  12. :start
  13. for /f "tokens=1* delims= " %%c in ('echo "!line!"') do (
  14.     set content=%%~c
  15.     set line=%%~d
  16. )
  17. if "!line!"=="" goto end
  18. set line=!line:~0,-1!
  19. if not "!line!"=="" goto start
  20. :end
  21. echo !content!
  22. exit /b 0
复制代码

作者: digitbear    时间: 2015-1-29 19:03

用sed 应该可以
作者: amwfjhh    时间: 2015-1-29 19:18

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1 delims=:" %%i in ('findstr /n /r "^:样本" %~s0') do set /a "nTag=%%i"
  4. if defined nTag (
  5. for /f "delims=" %%i in ('more +%nTag% %~s0') do (
  6. set "strLine=%%i"
  7. echo,原地址     : !strLine!
  8. call :_ShowAction "strLine"
  9. echo,处理后地址 : !strLine!
  10. )
  11. )
  12. pause & goto :EOF
  13. :_ShowAction
  14. (
  15. echo,"!%~1!" | findstr /c:"/" >nul && (
  16. set "%~1=!%~1:*/=!"
  17. call :_ShowAction "%~1"
  18. )
  19. goto :EOF
  20. )
  21. :样本
  22. http://www.bathome.net/post.php?action=newthread&fid=5
  23. http://www.bathome.net/c/3553908420
复制代码

作者: apang    时间: 2015-1-29 21:41

  1. @echo off & setlocal enabledelayedexpansion
  2. set Lf=^
  3. for /f %%a in ('copy /z "%~0" nul') do for %%b in ("!Lf!") do (
  4.         endlocal
  5.         (for /f "delims=" %%c in (a.txt) do (
  6.                 set "s=%%c"
  7.                 setlocal enabledelayedexpansion
  8.                 set "s=!s:/=/%%a%%~b!"
  9.                 echo,!s!
  10.                 endlocal
  11.         ))>$
  12. )
  13. findstr "[^/]$" $ > b.txt
  14. del $
  15. pause
复制代码

作者: 慕夜蓝化    时间: 2015-1-29 22:47

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set "str=%%i"&call :split
  4. )
  5. pause
  6. :split
  7. echo,"!str!"|find "/" >nul 2>nul ||echo,!str!&&goto :eof
  8. set "str=!str:*/=!"&goto :split
复制代码
你应该测试一下,我想了好几条思路,这样一来,字符串的任意提取,几乎没有了难度,所要做的就是接触更多的方法。
作者: amwfjhh    时间: 2015-1-30 00:38

回复 9# apang
  1. copy /z "%~0" nul
复制代码
请问apang,这句是作什么用的?去掉这层循环,单纯将/后加个回车也能得到正确的结果。
作者: CrLf    时间: 2015-1-30 04:42

回复 11# amwfjhh


    用于取回车符(由 plp626 发明),这样才能被 findstr 的 $ 匹配到(findstr 里判定 $ 的就是回车符)
    apang 的方案非常妙,意外惊喜,赞
作者: CrLf    时间: 2015-1-30 05:06

基于 apang 思路,来俩变化:
  1. @echo off
  2. set NLM=^
  3. set NL=^^^%NLM%%NLM%^%NLM%%NLM%
  4. for /f "delims=" %%a in (c.txt) do (
  5. set "str=%%a$"
  6. setlocal enabledelayedexpansion
  7. for /f "delims=" %%b in (^"!str:/^=%NL%!^") do (
  8. endlocal
  9. set "str=%%b"
  10. setlocal enabledelayedexpansion
  11. )
  12. echo !str:~,-1!
  13. endlocal
  14. )
  15. pause
复制代码
  1. @echo off
  2. for /f "delims=" %%a in (c.txt) do (
  3. set str=%%a
  4. setlocal enabledelayedexpansion
  5. set str=set "str=!str:/="^&set "str=!"
  6. call :getstr
  7. echo !str!
  8. endlocal
  9. )
  10. pause
  11. :getstr
  12. %str%
  13. exit /b
复制代码

作者: CrLf    时间: 2015-1-30 05:13

不过要说哪个方案比较通用,呃,如果不方便用第三方,那还是用 Bat+JS 吧
  1. 1>1/* : www.bathome.net
  2. @echo off
  3. cscript -nologo -e:jscript "%~0"<c.txt
  4. pause & exit /b
  5. */
  6. with(WSH){
  7. Echo(StdIn.ReadAll().replace(/.*\//gm,''))
  8. }
复制代码

作者: amwfjhh    时间: 2015-1-30 09:23

回复 12# CrLf


    回车替换是后面这句做到的嘛。
  1. for %%b in ("!Lf!") do
复制代码
!Lf!在前面已经赋值,但前面那句
  1. copy /z "%~0" nul
复制代码
还是不清楚是来干嘛的,有它没它,单凭后面那层循环也可以直接将回车(准确说是换行符)加到"/"字符之后。
作者: amwfjhh    时间: 2015-1-30 12:01

像这样把第一层循环屏蔽掉也可正常输出结果,弄不懂了。
  1. @echo off & setlocal enabledelayedexpansion
  2. pushd %tmp%
  3. set "启始行=:样本"
  4. for /f "tokens=1 delims=:" %%i in ('findstr /n /r ^!启始行! %~s0') do (set /a "nTag=%%i")&if defined nTag (># more +!nTag! %~s0) else goto :end
  5. set Lf=^
  6. REM for /f %%a in ('copy /z "%~0" nul') do
  7. for %%b in ("!Lf!") do (
  8.   (for /f "delims=" %%c in (#) do (
  9.   set "s=%%c"
  10.   echo,原字符串 : !s!
  11.   set "s=!s:/=/%%a%%~b处理后值 : !"
  12.   echo,处理后值 : !s!
  13.   ))>$
  14. )
  15. findstr "[^/]$" $
  16. del /f $ #
  17. :end
  18. popd
  19. pause & goto :EOF
  20. :样本
  21. http://www.bathome.net/post.php?action=newthread&fid=5
  22. http://www.bathome.net/c/3553908420
复制代码

作者: CrLf    时间: 2015-1-30 13:05

回复 15# amwfjhh


    昂,难道 findstr 版本不同?还是我记错了?
作者: apang    时间: 2015-1-30 18:01

回复 11# amwfjhh


    嗯,最外一层 for /f %%a in ('copy /z "%~0" nul') do 是多余的。

echo,!s! 已经在字串后面加上了回车换行,不加这一层循环,findstr "[^/]$" 也可以匹配到结果
作者: CrLf    时间: 2015-1-30 18:20

回复 18# apang


    噢,是这个理,看明白了
作者: apang    时间: 2015-1-30 19:01

本帖最后由 apang 于 2015-1-31 13:20 编辑

回复 16# amwfjhh


    看来我的思维定势很严重,总想到回车换行不应该分开,呵呵。

这样的话,findstr "$" $ > b.txt,匹配包含有回车的行

修改如下:
  1. @echo off
  2. if "%~1" NEQ "" (
  3.         setlocal enabledelayedexpansion
  4.         set Lf=^
  5.         for %%a in ("!Lf!") do (
  6.                 endlocal
  7.                 for /f "delims=" %%b in (a.txt) do (
  8.                         set "s=%%b"
  9.                         setlocal enabledelayedexpansion
  10.                         set "s=!s:/=%%~a!"
  11.                         echo,!s!
  12.                         endlocal
  13.                 )
  14.         )
  15. ) else "%~0" :|findstr $ & pause
复制代码

作者: lyfwcn    时间: 2015-1-31 10:03

本帖最后由 lyfwcn 于 2015-1-31 10:07 编辑

回复 13# CrLf

你这第二个又简单(其它的换个符号我就不知该变哪了)又能用又快,不过显示在黑屏上,按键复制它就关了,如何直接改文本啊。或者把c.txt变化后的放入d.txt啊。
  1.     @echo off
  2.     for /f "delims=" %%a in (c.txt) do (
  3.             set str=%%a
  4.             setlocal enabledelayedexpansion
  5.             set str=set "str=!str:$="^&set "str=!"
  6.             call :getstr
  7.             echo !str!
  8.             endlocal
  9.     )
  10.     pause
  11.     :getstr
  12.     %str%
  13.     exit /b
复制代码

作者: apang    时间: 2015-1-31 13:47

回复 21# lyfwcn


    亲,加一个重定向你都不会啊?

能用的话,给CrLf加分呗,不要这么吝啬。




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