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

[文本处理] [已解决]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命令排序的速度比我试过的文本编辑软件都快,尤其是那些利用插件提供排序功能的软件。

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

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

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

TOP

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

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

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

TOP

回复 7# buyiyang


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

TOP

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

回复 31# Five66


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

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

TOP

回复 29# ppll2030


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

TOP

回复 28# aloha20200628


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

TOP

本帖最后由 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)}"
复制代码

TOP

回复 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进行交互

TOP

回复 26# killer3k


    试试把 sort 后面的分割获取改为字符串获取第4个字符  { $_.Substring(3) } 试试

TOP

本帖最后由 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赵六

TOP

本帖最后由 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的配置文件在哪都还没找到,慢慢来吧。

TOP

回复 24# aloha20200628


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

TOP

回复 19# delab-1


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

TOP

本帖最后由 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
复制代码

TOP

返回列表