[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [分享]批处理命令sort不读写文件,按字节比较字符串

  1. rem csort.bat
  2. @rem 文件后缀名必须是 .bat ,如果是 .cmd 或 .dos,可能造成返回的 errorLevel 和预期不一致。
  3. :main_20230829_224931
  4. @echo off&setlocal EnableDelayedExpansion
  5. @rem  10    0x0a           <Line Feed>          换行符    调用方式: !$0a!
  6. set $0a=^
  7. @rem  10    0x0a           <Line Feed>          使用 ANSI 编码时,以上必须空两行,必须延迟取值 !$0a!
  8. echo.
  9. REM set "arg1=;!a!%0%%~`@#$&,.-_+{}[]\*()=|:"^'<>?/"
  10. REM set "arg2=;C=Fc"="
  11. set arg1=&set /p arg1=arg1=
  12. set arg2=&set /p arg2=arg2=
  13. cd.
  14. call :YNC "比较时是否区分大小写?" N && (
  15. call :Strcmp arg1 arg2 "/c" && echo arg1 == arg2
  16. if !errorlevel! EQU -1 echo arg1 ^< arg2
  17. if !errorlevel! EQU  1 echo arg1 ^> arg2
  18. cd.&rem 如果不重置的 errorlevel 值,会触发 || 分支。
  19. ) || (
  20. if !errorlevel! EQU 3 (echo "用户中断后续流程。"&cd.&goto :EOF)
  21. call :Strcmp arg1 arg2 && echo arg1 == arg2
  22. if !errorlevel! EQU -1 echo arg1 ^< arg2
  23. if !errorlevel! EQU  1 echo arg1 ^> arg2
  24. cd.
  25. )
  26. call :Strcmp arg1 "arg2" && echo arg1 == "arg2"
  27. if !errorlevel! EQU -1 echo arg1 ^< "arg2"
  28. if !errorlevel! EQU  1 echo arg1 ^> "arg2"
  29. echo.&pause
  30. @goto :EOF
  31. @rem Usage:
  32. rem 功能: 比较字符串。相等: errorLevel=0; 小于: errorLevel=-1; 大于: errorLevel=1;
  33. rem       按 C 语言环境比较,即对逐个字节按对应 ASCII 码值比较。默认不区分大小写。
  34. REM       传递参数用双引号括住,表示传递的是字面字符串,否则传递的是变量名。
  35. rem       兼容所有特殊字符,如果字符串只是单个双引号,需要赋值给变量,然后把变量名传递给 :strcmp。
  36. rem       而传递两个双引号,则表示传递空值。
  37. rem       比较不涉及读写文件,可以在内存中高效运行。
  38. :Strcmp <&s1, &s2, [,/c ...]>
  39. @echo off||Created by tiandyoin&title Strcmp s1 s2 (ignore case defaultly)
  40. @setlocal EnableDelayedExpansion
  41. set guid={D3B20598-09F8-4b22-8B47-BA7778B2C3F4}
  42. set "so=/L "C"" & if not "%~3"=="" set "so=!so! %~3 "
  43. if "%~1"=="%1" (set "s1=!%1!") else set "s1=%~1"
  44. if "%~2"=="%2" (set "s2=!%2!") else set "s2=%~2"
  45. echo.!so! | findstr /I /C:"/C">nul && (
  46. if    "!s1!"=="!s2!" exit /b 0
  47. ) || (
  48. if /i "!s1!"=="!s2!" exit /b 0
  49. )
  50. set "!guid!=!s1!!$0a!!guid!=!s2!"
  51. for /f "delims=" %%a in ('set !guid! ^| sort !so!') do (
  52. set guid=
  53. setlocal DisableDelayedExpansion
  54. set "str=%%a"
  55. setlocal EnableDelayedExpansion
  56. if "!str:~39!"=="!s1!" (
  57. @exit /b -1
  58. ) else (
  59. @exit /b 1
  60. )
  61. endlocal
  62. endlocal
  63. )
  64. @goto :EOF
  65. :: ---------------------------------------------------------------------------------------------------------------------
  66. @rem Usage:
  67. rem 功能: 判断是否按要求执行命令
  68. :YNC <Prompts ,[Y|N|C]>
  69. @echo OFF
  70. set "$=%~2"&if not defined $ set $=Y
  71. choice /C YNC /T 5 /D %$% /M "%~1 是请按 Y,否请按 N,或者取消请按 C。(5秒后默认为 '%$%')"
  72. if %errorlevel%==1 goto :YES
  73. if %errorlevel%==2 goto :NO
  74. if %errorlevel%==3 goto :CANCEL
  75.   @exit /b 1
  76. :YES
  77.   @cd.&goto :EOF
  78. :NO
  79.   @exit /b 2
  80. :CANCEL
  81.   echo "取消选择。不做任何修改。"
  82.   @exit /b 3
  83. @goto :EOF
复制代码
由于 if 的比较是根据本地语言习惯比较,并不直观。要按字符的ASCII码逐字节比较的,只能想新的办法。
这里利用了 sort /l "c" 的功能,加上管道,很好的比较两个字符串的大小。
1

评分人数

代码完全看不懂,真不愧是强者的世界

TOP

字节排序?
  1. @echo off
  2. powershell -noprofile -executionpolicy bypass "[char[]]([System.Text.Encoding]::Default.GetBytes('hello')|sort) -join ''"
  3. pause
复制代码

TOP

本帖最后由 buyiyang 于 2023-9-1 09:29 编辑
  1. sort /l "C" /c
复制代码
这里的 /c 是什么意思?

sort好像没有 /c 参数,C区域设置是不分大小写的,为什么加了/c就能区分大小写排序了?
  1. sort /l "C" /
复制代码
我试了一下 / 也能达到同样的效果。

另外,除了了sort参数列表有的之外,我分别拿26个字母做开关参数试了一下,都提示无效命令行开关,除了 /c 和 /u,使用 /u 会使输出成为Unicode。

TOP

回复 4# buyiyang


    /c 是区分大小写,应该是有效果的,我再试试

TOP

回复 3# Nsqs


    都用 Powershell , 直接跑 ps1 好了。win xp 用不了

TOP

回复 3# Nsqs


    只有一个 ’hello‘ ? 怎么排序多个串

TOP

回复 4# buyiyang
  1. set guid={D3B20598-09F8-4b22-8B47-BA7778B2C3F4}
  2. set s1=AbCdeFGHijklmnooppQs1
  3. set s2=ABCdeFGHIJKlmnooppQs2
  4. set s3=AbCdeFGHijklmNOOppQs3
  5. set s4=abCdefgHijklmnooppQs4
  6. set s5=AbcDEFGHIJKLMNooppQs5
  7. set s6=abCdeFghijklMNOOppQs6
  8. set s7=AbCdeFGHijklmnooppqs7
  9. set "!guid!=!s1!!$0a!!guid!=!s2!!$0a!!guid!=!s3!!$0a!!guid!=!s4!!$0a!!guid!=!s5!!$0a!!guid!=!s6!!$0a!!guid!=!s7!"
  10. set !guid! | sort /L "C" /C
复制代码
结果是有排序的:
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=ABCdeFGHIJKlmnooppQs2
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=AbCdeFGHijklmNOOppQs3
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=AbCdeFGHijklmnooppQs1
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=AbCdeFGHijklmnooppqs7
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=AbcDEFGHIJKLMNooppQs5
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=abCdeFghijklMNOOppQs6
{D3B20598-09F8-4b22-8B47-BA7778B2C3F4}=abCdefgHijklmnooppQs4

TOP

回复 5# tiandyoin
sort好像没有 /c 参数,C区域设置也不分大小写,为什么加了/c就能区分大小写排序了?

我是问 /c 开关为什么可以实现区分大小写,因为sort的参数列表和帮助文档都没有这个参数,而且空的开关 / 也能实现相同的功能

TOP

回复 9# buyiyang


    我用 Win11 , 你用什么版本

https://ss64.com/nt/sort.html

TOP

返回列表