反转匹配行,NUL 分隔

反转匹配行,NUL 分隔

我正在写一些处理文件匹配的东西,我需要一个反转操作。我有一个文件列表(例如来自find . -type f -print0 | sort -z >lst)和一个匹配列表(例如来自grep -z foo lst >matches– 请注意,这只是一个示例;matches可以是任何任意子集(包括空或完整)或lst),现在我想反转此列表。

背景:我正在实施类似的事情查找(1)例外文件列表(尽管文件在调用时确实存在于文件系统中,但该列表可能已被预先过滤)。如果文件列表不是那么大,我可以使用find "${files[@]}" -maxdepth 0 -somecondition -print0,但即使适度使用我正在编写的内容也会超出 Linux 或 BSDargv大小限制。

如果行不是用 NUL 分隔的,我可以使用comm -23 lst matches >inverted.如果匹配不是用 NUL 分隔的,我可以使用grep -Fvxzf matches lst.但是,从我在第一段中提到的生成器来看,两者都是。

假设安装了 GNU 工具,所以这不需要在 Debian 之外进行移植,因为我正在使用find -print0sort -z朋友已经(虽然一些 BSD 有它,所以如果它可以在“更便携”中完成,我不会抱怨) 。

我正在尝试在这里进行代码重用;另外,comm -23基本上已经是完美的工具了,除了它不支持更改输入行分隔符(尚),并且通讯无论如何,它是一个被低估且不够知名的工具。如果 Unix/Linux 工具箱没有提供任何明智的东西,我可能会comm -23在 shell 中重新实现一种形式(简化为这一个用例),因为脚本已经(出于其他原因)需要一个碰巧支持的 shellread -d ''对于 NUL 分隔的输入,但这会很慢(而且费力……我在工作日结束时发布了此内容,希望有人知道我明天或 28 日何时拿起它)。

答案1

如果您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'

那是一个常用技术

答案2

如果您使用 grep 来搜索匹配项,则可以使用-vgrep 选项来查找不匹配的行。

相关内容