mir*_*los 4 grep find files comm null
我正在写一些处理文件匹配的东西,我需要一个反转操作。我有一个文件列表(例如 from find . -type f -print0 | sort -z >lst)和一个匹配列表(例如 from grep -z foo lst >matches– 请注意,这只是一个示例;matches可以是任何任意子集(包括空的或完整的)或lst),现在我想反转这个列表.
背景:我正在实现类似于find(1) 之类的东西,除了文件列表(尽管文件在调用时确实存在于文件系统中,但该列表可能已被预先过滤)。如果文件列表可能没有那么大,我可以使用find "${files[@]}" -maxdepth 0 -somecondition -print0,但即使适度使用我正在编写的内容也会超出 Linux 或 BSDargv大小限制。
如果这些行不是 NUL 分隔的,我可以使用comm -23 lst matches >inverted. 如果匹配不是 NUL 分隔的,我可以使用grep -Fvxzf matches lst. 但是,从我在第一段中提到的生成器来看,两者都是。
假设GNU工具安装,所以这种需求无法移植超越例如Debian的,因为我使用find -print0,sort -z和朋友已经(虽然有些BSD系统有它,所以如果能在“更轻便”来完成,我不会抱怨) .
我正在尝试在这里进行代码重用;另外,comm -23除了它不支持更改输入行分隔符(尚)之外,它基本上已经是一个完美的工具,而且comm无论如何都是一个被低估且不够知名的工具。如果 Unix/Linux 工具箱没有提供任何合理的东西,我可能会comm -23在 shell 中重新实现一种形式(简化为这个用例),因为脚本已经(出于其他原因)需要一个恰好支持的 shellread -d ''对于以 NUL 分隔的输入,但这会很慢(和努力......我在工作日结束时发布了这个,希望有人知道我明天或 28 日何时拿起它)。
如果您comm支持非文本输入(就像 GNU 工具通常所做的那样),您可以随时交换 NUL 和 nl(这里使用支持进程替换的 shell(顺便说一句,您在 mksh 中有任何计划吗?)):
comm -23 <(tr '\0\n' '\n\0' < file1) <(tr '\0\n' '\n\0' < file2) |
tr '\0\n' '\n\0'
Run Code Online (Sandbox Code Playgroud)
这是一种常见的技术。