Files

反轉匹配行,NUL 分隔

  • April 16, 2019

我正在寫一些處理文件匹配的東西,我需要一個反轉操作。我有一個文件列表(例如 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 或 BSD 的argv大小限制。

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

假設已經安裝了 GNU 工具,所以它不需要移植到 Debian 之外,因為我正在使用find -print0sort -z朋友已經(雖然一些 BSD 有它,所以如果它可以在“更便攜”中完成,我不會抱怨) .

我正在嘗試在這裡進行程式碼重用;另外,comm -23基本上已經是完美的工具,除了它不支持更改輸入行分隔符(還),而且comm無論如何都是一個被低估且不夠知名的工具。如果 Unix/Linux 工具箱沒有提供任何有意義的東西,我可能會comm -23在 shell 中重新實現一種形式(簡化為僅這個案例),因為腳本已經(出於其他原因)需要一個恰好支持的 shellread -d ''對於 NUL 分隔的輸入,但這會很慢(而且很費力……我在工作日結束時發布了這個,希望有人知道我明天或 28 日什麼時候收到這個)。

如果您comm支持非文本輸入(就像 GNU 工具通常所做的那樣),您可以隨時交換 NUL 和 nl(這裡有一個支持程序替換的 shell(您在 mksh btw 中有任何計劃嗎?)):

comm -23 <(tr '\0\n' '\n\0' < file1) <(tr '\0\n' '\n\0' < file2) |
 tr '\0\n' '\n\0'

這是一種常見的技術

如果您使用 grep 搜尋匹配項,您可以使用-vgrep 選項來查找不匹配的行。

引用自:https://unix.stackexchange.com/questions/251154