反轉匹配行,NUL 分隔
我正在寫一些處理文件匹配的東西,我需要一個反轉操作。我有一個文件列表(例如 from
find . -type f -print0 | sort -z >lst
)和一個匹配列表(例如 fromgrep -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 -print0
和sort -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 搜尋匹配項,您可以使用
-v
grep 選項來查找不匹配的行。