我真的不知道如何制定这个,但我有一堆 IATA 代码,我想生成所有可能的组合,例如:JFK/LAX、BOS/JFK、...等,由一个字符分隔,例如“/”或“|”。
问问题
39 次
1 回答
1
这里我们假设您的 IATA 代码存储在文件中file
;每行一个代码。
crunch
具有-q
从文件生成行排列的选项。但是,在此模式下会crunch
忽略大多数其他选项,例如<max-len>
,这对于仅打印成对的代码很重要。
因此,...</p>
使用不同的东西crunch
例如,尝试
join -j2 -t/ -o 1.1 2.1 file file | awk -F/ '$1!=$2'
如果你真的、真的、真的想要,你可以……</p>
将输入翻译成crunch
可以使用的东西
我们将每一行从file
转换为一个唯一的单个字符,将该字符列表提供给crunch
,然后将结果转换回来。
crunch
支持 Unicode 字符,因此超过 255 行的文件完全可以。在这里,我们按字符枚举file
Unicode 的补充私人使用区域-A中的行。因此,file
最多可能有 65'534 行。
如果您需要更多行,您可以组合多个 Unicode 平面,但在某些时候您可能会遇到ARG_MAX
问题。此外,使用 65'534 行,您已经生成(略少于)65'534^2 = 4'294'705'156 对,转换为 IATA 代码对时占用超过 34 GB。
我怀疑反向翻译是一个巨大的减速,所以上述替代方案似乎在各个方面都更好(效率、简洁性、可维护性......)。
# This assumes your locale is using any Unicode encoding,
# e.g. UTF-8, UTF-16, … (doesn't matter which one).
file=...
((offset=0xF0000))
charset=$(
echo -en "$(bc <<< "obase=16;
max=$offset+$(wc -l < "$file");
for(i=$offset;i<max;i++) {\"\U\"; i}" |
tr -d \\n
)"
)
crunch 2 2 "$charset" -d 1@ --stdout |
iconv -t UTF-32 |
od -j4 -tu4 -An -w12 -v |
awk -v o="$offset" 'NR==FNR{a[o+NR-1]=$0;next} {print a[$1]"/"a[$2]}' "$file" -
于 2021-09-25T21:31:29.637 回答