Board logo

标题: [文本处理] [已解决]sort能正确处理utf-8格式的文本吗? /L[OCALE] locale 这个参数怎么用? [打印本页]

作者: killer3k    时间: 2024-10-4 20:22     标题: [已解决]sort能正确处理utf-8格式的文本吗? /L[OCALE] locale 这个参数怎么用?

本帖最后由 killer3k 于 2024-10-7 21:25 编辑

操作系统:win7

用了chcp 65001也没用,输出依然是乱码。
改了CMD窗口的字体,type命令倒是能正确显示utf8格式的文本文件,不会显示乱码,但sort命令输出的依旧是乱码。
如果先把文本转换为ANSI即GBK编码后,用sort命令倒是可以处理了,但这样一来又可能造成文本部分字符丢失。

另外,“/l[ocale] locale”这个参数怎么用?
这个完全搜索不到有用的资料,要么没说,要么照抄帮助文件,要么就是抄
http://www.bathome.net/viewthrea ... &highlight=sort
这篇,文章最后都是这句话,“没讲的内容,/l参数,这个是区域设置相关,我也没弄懂。”

复制一下srt命令帮助:
/L[OCALE] locale            用指定的区域设置替代系统默认区域设置。
                                       ""C"" 区域设置产生最快的排序顺序并且是当前
                                       的唯一其他选择。排序总是不分大小写的。

还有从微软帮助网站上复制来的内容:
/l <locale>         重写由系统默认区域设置(即在安装过程中选择的语言和国家/地区)定义的字符排序顺序。
注解:目前,默认区域设置的唯一替代方法是 C 区域设置,它比自然语言排序更快(它根据字符的二进制编码进行排序)。

26个英文字母的大小写我都试了,除了大写C,其它都会显示“无效的区域设置”,"zh-CN"、“en-US"、"0804"之类的也试过。
至于sort /l "C",这个参数用了也不知道会起什么作用。


最后,我想问一下,type,findstr等命令可以通过改变活动代码页,命令窗口字体等来解决不能正确处理utf8中文文本的问题,那么,sort命令到底有没有办法正确显示utf8文本?如果能确定sort命令本身无论如何都做不到的话,我就死心了,不折腾了。

还有,有没有可以替代sort的第三方程序,要能按拼音排序的。比如说linux下sort的windows版本能做到按拼音排序吗?我在电脑上找到一个十多年前的windows版本的linux下的sort命令,简单试了一下,不太会用,但貌似是按unicode排序,也不知道有没有相关区域设置的参数。

我现在主要用notepad2,notepad2没有指定从第几列开始排序的功能(可以变通做到,但操作不方便),所以是用批处理来辅助完成按指定列排序的功能,但无法处理utf8格式的文本。
notepad2的功能毕竟还是弱了点,所以一直准备换一个,但这些年都没找到十分满意的文本编辑软件。
最近准备好好学习一下VIM怎么用,VIM自身的sort命令依然是只能按照unicode排序,不能按拼音排序(据说要用插件,但是我也没找到)。不过VIM可以调用外部命令,和CMD的sort结合,可以完美解决ansi编码(GBK,cp936)文本按拼音排序的问题,但是无法解决utf8文本按拼音排序的问题。

顺便说一下,我感觉CMD的sort命令排序的速度比我试过的文本编辑软件都快,尤其是那些利用插件提供排序功能的软件。
作者: delab-1    时间: 2024-10-4 21:05

我也遇到同样的问题,sort后输出的文件中的中文都变成乱码,测试了很多方法都没有成功。chnp 65001没有任何用处。看看有没有大佬们给与指导
作者: ppll2030    时间: 2024-10-4 21:35

回复 1# killer3k


    chcp 65001是可以正常显示的,cmd窗口属性,换个字体就可以了。
作者: killer3k    时间: 2024-10-4 22:05

回复 3# ppll2030

刚又试了一下,还是没用。
作者: delab-1    时间: 2024-10-4 22:41

回复 3# ppll2030


    对sort而言,感觉仅仅写chnp=65001是肯定不行的
作者: Five66    时间: 2024-10-4 23:00

sort的/L参数大概是排序顺序,影响排出来的顺序,无效或许还没实现,只能是C?

chcp 65001时,要在cmd窗口里显示得设置字体,输出到文件可以不用设置字体,只是sortt输出时不知咋的utf8字符的某些字节码被转成问号(?),会导致某些部分乱码,而输出文件的编码是无bom的utf8,文本编辑器打开这个文件时很大概率会将编码识别为ansi(简体中文下是gbk)

type是好像单纯以换行符做为分割点的来输出,输出的内容由cmd根据当前代码也来解读(例如936代码页时按gbk解读,65001代码页时按utf8解读)

finstr貌似不支持非英文的utf8(例如中文),因为asni英文和utf8英文是一样的
作者: buyiyang    时间: 2024-10-4 23:14

sort的编码转换确实有问题,使用chcp 65001后将结果重定向到控制台可以正确显示,但有一些典型(没有显著编码特征)没有正确转码:比如“联通”“嘉峪关”等等;将结果重定向到文件无法正确显示,使用sort 1.txt | find /v "" 转码一下可以正确显示但也有前面的问题。

/L[OCALE] locale 微软帮助已经说得很清楚了,它默认按照本地语言环境进行自然语言排序和比较,要改的只能用locale C,C是按字符编码排序的,是唯一的。不同的语言环境的排序、日期、货币格式等都有一些不同,比如中文的zh_CN.GB2312给中文排序会按拼音排序,一些拉丁文的希腊字母会排在英文字母前面,一些欧洲文字不区分变体,等等。
说到拼音排序,其实前面提到的本地语言环境就已经规定了排序方式,是中文系统就是按拼音排序(文件资源管理器就是这样的),可以直接调用api,使用strCmpLogicalW函数,比如:
  1. Add-Type @"
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Runtime.InteropServices;
  5. public static class Localsort
  6. {
  7.     [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
  8.     public static extern int StrCmpLogicalW(string p1, string p2);
  9.     public static string[] Sort(string[] s)
  10.     {
  11.         Array.Sort(s, StrCmpLogicalW);
  12.         return s;
  13.     }
  14. }
  15. "@
  16. $inputFile = "origin.txt"
  17. $outputFile = "sorted.txt"
  18. $lines = [IO.File]::ReadAllLines($inputFile)
  19. $sortedLines = [Localsort]::Sort($lines)
  20. [IO.File]::WriteAllLines($outputFile, $sortedLines, [Text.Encoding]::UTF8)
复制代码

作者: ppll2030    时间: 2024-10-4 23:26

回复 4# killer3k
回复 5# delab-1


    我这边貌似没有问题,不过中文排序可能就不好用

作者: delab-1    时间: 2024-10-4 23:39

回复 7# buyiyang


    这个是C语言吧?能直接在批处理中调用吗?我这边不能测试
作者: delab-1    时间: 2024-10-4 23:51

回复 7# buyiyang


利用chcp 65001和 sort temp.txt | find / ""组合后,会好很多,大部分中文会正常显示,但是依然会出现奇怪问好“?”等字符。
chcp 65001
sort /R temp.txt | find /v "" >list.txt
list.txt

通过上面的程序,很多中文都正确显示了,但是部分不行。例如,“以色列”,显示为“以色??”

期待大家继续讨论,看看如何解决。
作者: Five66    时间: 2024-10-5 00:59

本帖最后由 Five66 于 2024-10-5 01:21 编辑

可以试试用unicode,将txt编码保存为unicode(utf16-le)
又或者试试将utf8编码的txt每一行都放进带前缀的变量里,然后:set 前缀|sort
不过建议最好放弃,就如之前(6楼)说的那样,sort不完全支持utf8,用powershel吧,虽然慢了点,但是里面的sort排序结果跟这个sort也差不多,,可以自行指定编码,也可以自定义排序规则
作者: flashercs    时间: 2024-10-5 11:59

排序跟编码没有关系,只跟Locale有关系,因为排序时比较的都是Unicode字符;只是sort.exe不支持utf-8,会乱码.
系统 "区域和语言"中可以修改 中文排序方式,按照 拼音 或 笔画
中文简体LocaleId是2052,在同样是2052的情况下,排序算法有可能不同.
Windows自带的.sort.exe跟powershell.exe的排序算法是一致的,中文排序是按拼音排序的,跟系统 "区域和语言"设置的 排序无关.
  1. #
  2. $
  3. @
  4. _
  5. 0
  6. 1
  7. 2
  8. 3
  9. a
  10. b
  11. c
  12. d
  13. e
  14. f
  15. 啊a
  16. 吧b
  17. 从c
  18. 的d
  19. 额e
  20. 发f
复制代码
pwsh.exe排序与之不同,1.中文在英文字母前面;2.中文排序跟系统 "区域和语言" 设置的排序规则有关系.
按 拼音 排序
  1. _
  2. @
  3. #
  4. $
  5. 0
  6. 1
  7. 2
  8. 3
  9. 啊a
  10. 吧b
  11. 从c
  12. 的d
  13. 额e
  14. 发f
  15. a
  16. b
  17. c
  18. d
  19. e
  20. f
复制代码
按 笔画 排序
  1. _
  2. @
  3. #
  4. $
  5. 0
  6. 1
  7. 2
  8. 3
  9. 从c
  10. 发f
  11. 吧b
  12. 的d
  13. 啊a
  14. 额e
  15. a
  16. b
  17. c
  18. d
  19. e
  20. f
复制代码
通过比较发现,原来.NET Framework与.NET Core的排序版本不同,后者版本更高.
又发现浏览器JavaScript的string对象的方法localCompare(str2,?locale,?option)可以指定locale,当locale=='zh-cn'时,排序结果与.NET Core版本一致.这说明 Core版本的CompareInfo的版本是最新版.
作者: aloha20200628    时间: 2024-10-5 16:05

本帖最后由 aloha20200628 于 2024-10-5 21:11 编辑

回复 1# killer3k

能够完好排序包含中文字符的utf-8编码文件的一个可选方案,已在win8.1系统测试通过...》
一。从本坛第三方下载 sort v7.6 (http://bcn.bathome.net/s/tool/index.html?key=sort) 命名其为 sort76.exe 使用
二。切换至65001码页,设置一个环境变量 set "lc_all=c",运行 sort76.exe "in_u8.txt" -o "out_u8.txt",其排序结果须输出到文件,示例代码如下
  1. chcp 65001>nul&set "lc_all=c"
  2. sort76.exe "in_u8.txt" -o "out_u8.txt"
复制代码
三。输出文件继承源文件的换行符格式,如要转换结果文件的unix换行符为pc换行符,可用如下代码(其中 sed.exe 可从本坛第三方下载 http://bcn.bathome.net/s/tool/index.html?key=sed
  1. set "lc_all=" &sed.exe "s/\r/\r\n/g" "out_u8.txt" -o "out_u8.new.txt"
复制代码
测试文件 in_u8.txt 如下,用utf-8编码保存:
  1. D:\music\@artists\Thaïs, Act II:Méditation.mp3
  2. D:\music\@artists\魂縈舊夢 Endless Dreams.flac
  3. D:\music\@artists\沉思 (Deep Thought).flac
  4. D:\music\@artists\Csárdás.mp3
复制代码

作者: killer3k    时间: 2024-10-5 19:08

回复 7# buyiyang


    我不懂编程,你写的内容太高深了。
    但这几天看了不少相关文章,感觉你说的是对的,windows下可以直接高API或其它我也不知道叫啥名的术语。但是有很多程序,不光是外国的,就算是国产的,也不按这个来啊,就是单纯按unicode码表的顺序排。
    另外,我看有些讨论怎么按拼音排序来编程的文章,都说要先做一个拼音库,感觉很奇怪,为什么不用现成的呢?比如说notepad2那么小个外国软件,无论是ansi还是utf8下都可以按拼音排序,那么他怎么可能去做一个拼音库呢?
    还有,这几天查了后才知道,GB2312中只有一级汉字是按拼音来排序,二级汉字是按笔划还是偏旁来排的。GBK完全兼容GB2312,那么同样只有GB2312中的一级汉字是按拼音排序。
作者: killer3k    时间: 2024-10-5 19:10

回复 8# ppll2030


    又试了几次,还是不行,cp936下有点阵和新宋两种可设,cp65001下有三种字体可设,都不行。会不会是因为我还在用win7的原因呢?
作者: killer3k    时间: 2024-10-5 19:11

回复 10# delab-1
在我的win7下,用findstr的话,全是乱码,用find的话,啥都没有。
作者: killer3k    时间: 2024-10-5 19:15

回复 12# flashercs


    不懂编程,感觉你说得对。但有些软件就是不按local的来,完全按unicode中的顺序罗列。比如说sublime text等文本编辑软件都是这样,排序后的汉字一看就是unicode的码表中的顺序。
作者: killer3k    时间: 2024-10-5 19:33

回复 13# aloha20200628


    谢谢,是那个180M的包中的吗?好东西,我先保存了。
    不过我的是win7,无效。
    估计是 set "lc_all=c" 这个设置在windows或win7以下版本无效吧。这两天搜索资料时见过这个命令,好像是linux下的命令,在windows下只有在cygwin环境下可以设置,设置后linux版的sort命令就可以按拼音排序了。
作者: delab-1    时间: 2024-10-5 20:19

回复 13# aloha20200628

目前看,这个运行效果非常好,中文显示完全没有问题,为了方便大家,我把运行程序写在下面:
if exist out_u8.txt del out_u8.txt
copy code2_chksort.txt temp.txt

chcp 65001>nul & set "lc_all=c"
sort76.exe "temp.txt" -r -o "out_u8.txt"
::这个地方注释下,在sort76.exe 下,其输处选项用的是-r (代表倒序) -o是输出文件,这个win自带的sort.exe写法不同,请大家注意。
out_u8.txt

另外论坛自带的sort.exe的下载步骤:
1)进入论坛主界面,在页面最下面的左角有一个“在线第三方下载”
2)点入进入页面以后,在顶部有一个关键词搜索框,在其中输入sort.
3) 就会出现sort版本,点击就可以下载下来了。

再次感谢无私的帮助,再次感谢大家的努力!比较完美的解决了问题
作者: ppll2030    时间: 2024-10-5 20:35

回复 15# killer3k


    我是用lucida console字体。前面测试过于简单了。
utf-8编码,type可以正常,sort却不能,我也发现某些汉字依然乱码了。正如上面大佬说的。
所以不用纠结了  换个方式吧。
作者: killer3k    时间: 2024-10-5 21:00

回复 19# delab-1


    win7没用,估计和操作系统有关。
作者: killer3k    时间: 2024-10-5 21:00

回复 20# ppll2030


    死心了死心了。
作者: killer3k    时间: 2024-10-5 21:09

本帖最后由 killer3k 于 2024-10-6 20:55 编辑

非常感谢各位!
死心了,准备试试powershell。
不过我不会powershell,vim也才用两三天,几乎可以说还不会。
win7下默认的powershell才是2.0,估计还得升级,这个还得研究一下。

目前只是搞定了在powershell中简单排序的命令,从指定的第几个字符开始排序还没搞定(即相当于sort /+5的方式)。

因为我的目的是在gvim的命令行模式下用命令调用外部程序,所以
get-content asdf.txt |sort-objectl这种方式可能还不行,sort-objectl前面必须是个变量才行。

估计是我的问题太简单了,所以网上也搜不到有用的资料,尽是些怎么在powershell中使用vimr 文章。

唯一有用的是百度AI给出了一条命令,但说实话,百度AI有时候给出的代码根本用不了,所以我也不知道对不对。
:1,10!powershell -Command "& {$_}" | Sort-Object
感叹号及以前不用管,后面符合powershell语法吗?

刚开始学vim,什么都不会,说的也不一定对。
先简单说一下vim调用外部命令的方式,供没用过vim的朋友参考。

:!外部命令表达式

冒号相当于CMD的命令提示符,感叹号表示调用的外部命令。
vim是用打开一个cmd窗口的方式来调用外部命令,

在CMD提示符后显示的是:
cmd.exe /c (外部命令表达式)

说一下我使用成功的例子

:%!sort /+5          # 对当前文本排序
:'<,'>!sort /+5      # 对当前选中文本排序
:1,3!sort /+5        # 对当前文本的1-3行排序

:1,3!powershell -command "get-content asdf.txt | sort-object"
这条命令如果把双引号去掉的话就会出问题,CMD会把|后面的sort-object当成CMD命令来执行。

显示结果:
'sort-object' 不是内部或外部命令,也不是可运行的程序或批处理文件。

上面我抄来的那条命令就更麻烦了。
:1,10w !powershell -Command "& {$_}" | Sort-Object
(为了方便观察试错,所以在1,10后又加了个w,表示不改写文件,这样就只会在CMD窗口中显示。
因为有"、&、|三个特殊符号,在CMD中执行就会有问题,如果原样执行的话,同样是把sort-object当成了CMD命令。

CMD窗口中的命令行显示的是这样的,供参考:
C:\Windows\system32\cmd.exe /c (^(powershell -command ^"^& {$_}^" ^| sort-object^) ^< C:\Users\用户名\AppData\Local\Temp\V51D7f0.tmp)
'sort-object' 不是内部或外部命令,也不是可运行的程序或批处理文件。
shell returned 255
Hit any key to close this window...

V51D7f0.tmp 这个是vim截取1到10行后生成的临时文件,不用管文件名是什么。

如果前后加上双引号的话,
:1,10w !powershell -Command ""& {$_}" | Sort-Object"

运行显示如下:
C:\Windows\system32\cmd.exe /c (^(powershell -command ^"^"^& {$_}^" ^| sort-object^) ^< C:\Users\用户名\AppData\Local\Temp\V51EC03.tmp)
'{$_}" | sort-object' 不是内部或外部命令,也不是可运行的程序或批处理文件。
shell returned 255
Hit any key to close this window...

加了双引号后,就直接把&符号后的{$_}" | sort-object全部当作是CMD命令了。

可以看出来,vim会自动把特殊符号转义后再用cmd.exe来执行,那么问题就是
powershell -Command "& {$_}" | Sort-Object
这条命令我应该怎么写才能让CMD正确执行?
当然,前提是这条powershell命令是正确的,如果这条命令本身就不正确,那么正确的命令应该怎么写?
我想要的是:
powershell -command 获取当前变量 | sort-object

对了,我电脑powshell目前版本还只是2.0,win7好像最高只能升到5.1,所以请提供适用于5.1以下版本的命令。

还有,我想问一下powshell怎样做才能达到 “sort /+5”这样的目的?
最好是一行代码,这样好执行。
网上也找不什么资料,百度AI倒是给出两个参数 -First 和 -Skip,但是百度一会说这是略过的行,一会说这是略过的字符。
我试了一下,比如说 -first 5 是只显示前5行,-skip 5 是不显示前5行。
作者: aloha20200628    时间: 2024-10-5 21:54

本帖最后由 aloha20200628 于 2024-10-5 22:46 编辑

回复 23# killer3k

以下各段代码在cmd窗口命令行直接运行,在 win7/powershell v2 环境下试一试也许也能通过

采用 powershell v3+ 对(ansi 或 gb2312 编码)文本文件 test.txt 中第3个字段按字符值排序
  1. powershell "gc test.txt | sort {$_.split(',')[2]}"
复制代码
采用 powershell v3+ 对(utf-8 编码)文本文件 test.txt 中第3个字段按字符值排序
  1. powershell "gc test.txt -enc utf8 | sort {$_.split(',')[2]}"
复制代码
采用 powershell v3+ 对文本文件(ansi 或 gb2312 编码) test.txt 中第2个字段按整数值排序
  1. powershell "gc test.txt | sort {[int]$_.split(',')[1]}"
复制代码
采用 powershell v3+ 对文本文件(utf-8 编码) test.txt 中第2个字段按整数值排序
  1. powershell "gc test.txt -enc utf8 | sort {[int]$_.split(',')[1]}"
复制代码
测试文件 test.txt 如下
  1. 簡轉繁,9,zyx
  2. 繁轉簡,222,hijk
  3. 采用powershell_v4排序第n列字段,11,ab
复制代码

作者: killer3k    时间: 2024-10-6 20:24

回复 19# delab-1


    昨天没成功,今天又试了一下,可以正确显示汉字了(都是复制的相同的代码)。
    不过感觉还是不能解决汉字排序的问题,set LC_ALL="C" 后就没有本地化设置了,汉字就不能按照拼音排序了。
    简单试了一下,功能比CMD的sort强,但我没找到相当于sort /+n参数的功能,速度不如CMD的sort。
作者: killer3k    时间: 2024-10-6 20:35

回复 24# aloha20200628


    非常感谢,写了4段代码,真是费心了,而且我感觉你给的这段代码要比百度AI抄来的好。
    感觉split这个东西很有用啊,好像可以用来处理CSV文件。
    对照着看,大致看懂了,也试了一下,win7 powershell2.0下也完全能运行。
    不过,这个split好像必须有分隔符,我试着把分隔符删掉,好像就是把整行当作一个对象。
    我想要的是相当于 sort /+n 的功能,不根据分隔符,而直接从指定的字符位置来开始排序。
    比如说:
    aaaa张三
    bbbb李四
    cccc王五
    dddd赵六
    忽略掉每行的前四个字符,根据每行的第五个字符及之后的文字来排序,这个功能,powershell能不能实现?如果能我就再研究,如果不能我就考虑别的办法。
    以前总觉得powershell太慢,所以不想学,不过现在感觉好像还是可以学一点的。
    再次感谢。
作者: killer3k    时间: 2024-10-6 20:53

本帖最后由 killer3k 于 2024-10-6 20:54 编辑

仔细研究了一下,感觉我目前想通过VIM的命令行来调用powershell,达到对文本排序的目的是不可能实现的。问题出在目前我唯一知道的VIM调用外部命令的方式上(可能VIM还有别方法我没接触到)。
VIM是通过把“全文、指定行、选择行”的内容生成一个临时文件,再把这个临时文件传递给外部命令排序,然后再把排序结果覆盖前述指定的内容。
问题就在VIM调用外部命令的方式是:
在VIM命令行输入
:{指定范围} !外部命令表达式
然后用cmd调用这个外部命令表达式,简化一下:
cmd.exe /c (^(外部命令^) ^< 临时文件)
所以,实际上VIM是直接把这个临时文件用重定向符“<”传递给外部命令来处理,而不是把这个临时文件的路径文件名作为参数传递给外部命令。
简单看了一下powershell的帮助,powershell好像不能通过重定向符“<”来接收文件内容。
实际上,CMD中能通过“<”这个重定向符接收文件内容作为输入的命令也是少之又少。
对了,不知道批处理bat文件有没有办法把重定向符“<”之后文件名作为参数传递到批处理文件内,如果行的话,似乎还有点办法。

感觉还是得通过VIM想办法,可能需要写一个VIM脚本,不过我现在连VIM的配置文件在哪都还没找到,慢慢来吧。
作者: aloha20200628    时间: 2024-10-6 21:48

本帖最后由 aloha20200628 于 2024-10-6 21:54 编辑

回复 26# killer3k

比对 sort /+n 的功能,以下代码调用 powershell 对 test.txt 文件每行第3个字符开始排序,在cmd窗口命令行直接运行...
      powershell "gc test.txt | sort {$_[2..$_.length]}"
示例文件 test.txt 内容如下:
a1xa张三
b9bb李四
c5zc王五
d2dd赵六

作者: ppll2030    时间: 2024-10-6 21:51

回复 26# killer3k


    试试把 sort 后面的分割获取改为字符串获取第4个字符  { $_.Substring(3) } 试试
作者: Five66    时间: 2024-10-6 22:09

回复 23# killer3k


   
看起来vim是重定向输入数据的,ps并不会自动处理,你得自己手动解决,例如下面的
  1. powershell -c "[io.streamreader]::new([console]::OpenStandardInput(),[text.encoding]::utf8).readtoend() -split '\r?\n' |sort"
复制代码
sort /+5这样的功能不自带,你得自己转换,然后处理,例如下面的($l=4中的4就是,从0开始)
  1. powershell -c "$l=4;[io.streamreader]::new([console]::OpenStandardInput(),[text.encoding]::utf8).readtoend() -split '\r?\n' |foreach{if($_.length -gt $l){,@($_.substring($l,$_.length-$l),$_)}else{,@($_,$_)}}|sort {$_[0]} |foreach {$_[1]}"
复制代码
嫌复杂可以将代码放进一个bat里,然后带参数调用这个bat,在bat中只要根据参数执行对应的powershell代码就行了

poswershell中的sort命令排序时会忽略英文减号(-)之类的字符,排序结果可能跟sort.exe的结果不一样

还有poswershell很多东西都跟常规的不一样,除非非常熟悉,不然不建议跟外部程序进行交互,外部程序也不建议跟poswershell进行交互
作者: Five66    时间: 2024-10-7 00:11

本帖最后由 Five66 于 2024-10-7 00:23 编辑

回复 30# Five66


   
改正下,sort /+5功能能搞错了,换成下面的($l=4中的4就是,从0开始)
  1. powershell -c "$l=4;[io.streamreader]::new([console]::OpenStandardInput(),[text.encoding]::utf8).readtoend() -split '\r?\n' |where{$_}|group {$_.length -gt $l} |foreach {if($_.name -eq $true){$t=$_}else{$f=$_}};$f.group|sort;$t.group |sort {$_.substring($l,$_.length-$l)}"
复制代码

作者: killer3k    时间: 2024-10-7 19:38

回复 28# aloha20200628


    非常感谢,成功了。
    就是对长度没到指定位置的字符串不知道是采用什么顺序排的,我试着在文本中添加了 0-9 和 a-z 的单字符,完全看不出是按什么顺序排的。
    不过没关系,我一般不会碰到这种情况,真遇到了就人工处理一下。
    等将来powershell懂得多一点后,估计可以写个脚本,先判断,再排序,慢慢来吧。
    现次感谢。
作者: killer3k    时间: 2024-10-7 19:42

回复 29# ppll2030


        非常感谢,也成功了。
        这种方法和前面 sort {$_[2..$_.length]} 相比,如果一行字符长度不到指定位置的话,会有一个错误提示,但不影响排序。
        估计这两种方法可以应用于不同场景,当然,我现在还想不到,慢慢学吧。
        再次感谢。
作者: killer3k    时间: 2024-10-7 19:52

本帖最后由 killer3k 于 2024-10-7 20:08 编辑

回复 31# Five66


    对于我来说,内容太深奥了。
    实际上,我是看了你说的用Powershell后才算是正式开始接触powershell的,也就这两天的事。以前大概也就是在powershell中试着输入过dir,不过那肯定不算数。
    你写的内容我先保存了。大概能猜出来用了循环、条件语句,和输入、数组之类的有关。感觉很有用,将来肯定用得上,所以先保存下来再慢慢研究。
    非常感谢。

    对了,要是没你的指导,我还没真想到去用powershell,因为一直觉得这个太慢了。
    这两天试了一下,感觉虽然运行速度不怎么样,但功能还挺强大的。
    再次感谢。
作者: killer3k    时间: 2024-10-7 20:04

回复 7# buyiyang


    懂了懂了,这几天反复试验,感觉弄懂  /L[OCALE] locale 的意思了。
    如果不加 “ /L "C" ” 的话,排序顺序就是依据操作系统的本地设置,在中文操作系统上就是按拼音或笔划来排序(根据设置不同)。
    如果加了 “ /L "C" ” 的话,则会去掉所有本地化设置,排序不会依照本地化设置来。大概和 LC_ALL=C 中的C一样,其中“C”代表使用ANSI C的标准环境,即不使用任何特定的本地化设置。
    终于弄懂了,非常感谢。
作者: killer3k    时间: 2024-10-7 20:26

非常感谢各位的帮助,现在总算是解决在命令行下怎么对文本排序的问题了,而且有了一个学习方向。

用powershell来对文本排序,虽然速度不怎么样,但总算是解决了有没有的问题,至于好不好的问题,只能等我将来多学点后再完善了。

总结一下个人看法:
如果不需要在命令行下操作的话,就去找一个能够对unicode格式的文本中的汉字根据拼音来排序的文本编辑软件吧。
如果需要在命令行下操作的话:
1、ansi文本可以用CMD的sort,功能虽然不是很多,但速度最快。如果需要更多的功能的话,可以用前面
有网友推荐的sort76.exe。
sort76.exe 是GnuWin32套件中从linux移植到windows的一个小命令行工具,可以在本论坛的第三方命令板块中找到下载位置,安全性应该还是有保障的。查看帮助是 “sort76.exe --help”。
2、如果是unicode文本,如果没有对汉字根据拼音来排序的要求的话,可以用 sort76.exe。
3、如果是unicode文本,如果需要对汉字根据拼音来排序的话,那就用powershell吧,缺点就是对较大的文件排序的速度比较慢。
当然,如果自己会编程的话,就自己写程序吧。仰望!
再次感谢各位的帮助。
作者: killer3k    时间: 2024-10-7 20:40

至于怎么把powershell和vim结合起来,因为两者我都是刚接触,只能瞎想一下。

写一个vim脚本(怎么写,过一段时间再学,先把我需要的常用的vim基本操作熟悉一下再说吧),
然后用vim命令把选中的内容保存到一个临时文件,
用powershell对这个临时文件处理,
最后用vim命令把这个临时文件的内容写回文件。

不管怎么样,总算是有了一个学习方向吧。




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