我编写了一个 bash 脚本,它处理文件名列表(使用 glob 扩展,如 中所示for f in *
),然后将该列表的子集输出到文件。随后,我将该文件的内容读入数组,并使用明显的<
和>
运算符来比较字符串,对特定文件名执行简单的二进制搜索。
考虑到我希望该脚本能够在许多不同的环境中工作,例如 Linux、MacOS、MinGW 等(尽管它使用类似[[
和stat
等可移植性较差的环境),我的问题是:
- 我是否需要对文件内容进行排序(使用
sort
或附加 bash 代码),或者 glob 扩展是否始终在每个环境中进行排序? 条件运算符是否使用与扩展(或之后
sort
)相同的“排序”?会在之后扩展或
sort
返回(在什么情况下?),但使用条件运算符会在之前?我将使用什么选项来解决这个问题?file10.txt
file2.txt
file10.txt
file2.txt
sort
如果我的某些文件名采用 Unicode,有什么注意事项吗?
- 使用特定版本的 bash 是否存在任何问题?
- 是否
LC_COLLATE
影响以上任何一项?
显然,我需要文件内容与运算符的排序“方法”相匹配,以便二分搜索能够按预期工作......
答案1
是的,全局扩展总是经过排序的。
在 bash 中(来自LESS=+/'^ *Pathname Expansion' man bash
)
路径名扩展...该单词被视为一种模式,并且替换为按字母顺序排序的与模式匹配的文件名列表。
这也是由 POSIX glob 指定:
...路径名按 LC_COLLATE 类别的当前设置定义的排序顺序排列。
注1: 除非GLOB_NOSORT
设置了标志。在这种情况下,顺序是未指定的。
笔记2:排序顺序为字母顺序(非数字),10 排在 2 之前。
答案:
- 我是否需要对文件内容进行排序(使用排序或附加 bash 代码)...
Globing 与文件内容无关,仅适用于文件名。
如果您需要对“文件内容”进行排序,那么,是的,您确实需要调用sort
use 相当多的bash
代码。
- ...或者全局扩展总是排序的 - 在每个环境中?
除非禁用,否则Globing 的结果将按照环境中GLOB_NOSORT
排序顺序(变量)定义的顺序进行排序。LC_COLLATE
要具有相同的排序顺序,您必须具有相同的有效排序规则。两者都设置LC_COLLATE
变量并具有locale
包含相同整理详细信息的描述。
- 条件运算符是否使用与扩展(或排序后)相同的“排序”?
是的。两者都受到相同的影响LC_COLLATE
。
- 扩展或排序是否会在 file2.txt 之后返回 file10.txt (在什么情况下?),但使用条件运算符 file10.txt 将在 file2.txt 之前?我将使用什么排序选项来解决这个问题?
10
before的结果2
是“字典顺序”,与 bash 手册描述中所谓的“字母顺序”相同。因此,如果您使用 bash(或任何 POSIX shell)进行排序,这就是您将得到的顺序(在所有情况下)。这没有错,所以它是不可修复的(对于文本)。
但是,如果您选择使用sort
(外壳外部的外部工具),您可能会要求numeric
排序(-n 选项),它将2
放在10
.或者您可以从文本中提取数字并使用它们-lt
-gt
在 shell 中进行整数比较(整数运算符)。
如果我的某些文件名采用 Unicode,有什么注意事项吗?
大多:整理顺序不固定。
它随时间和 UNICODE 版本而变化。
可能发生的情况是,您用某种您不熟悉的语言得到一些令人惊讶的结果。例如:
简而言之:“准备好感到惊讶”。
使用特定版本的 bash 是否存在任何问题?
嗯,你必须使用2.0以上的bash版本
respect LC_COLLATE 2.0
LC_COLLATE 会影响上述任何一个吗?
变量LC_COLLATE
影响全部上述的。