次に終わる回答list2
別の質問として、次の構造を使用して表示されますが、表示されないファイルを探したいと思いますlist1
。
( cd dir1 && find . -type f -print0 ) | sort -z > list1
( cd dir2 && find . -type f -print0 ) | sort -z > list2
comm -13 list1 list2
しかし、私のバージョンがNULLで終わるレコードを処理することができないため、問題が発生していますcomm
。 (一部の背景情報:計算リストをに渡すので、rm
特に新しい行が含まれる可能性があるファイル名を処理できるようにしたいです。)
簡単な例が必要な場合は、これを試してください
mkdir dir1 dir2
touch dir1/{a,b,c} dir2/{a,c,d}
( cd dir1 && find . -type f ) | sort > list1
( cd dir2 && find . -type f ) | sort > list2
comm -13 list1 list2
NULLで終わる行がない場合、ここの出力は./d
に現れる単一の要素だけですlist2
。
find ... -print0 | sort -z
リストを作成したいです。
comm
に表示されますが、表示されないNULL終了レコードを出力する同等のものを再実装するための最良の方法は何ですか?list2
list1
ベストアンサー1
GNU comm
(GNU coreutils 8.25ベース)には-z
/--zero-terminated
オプションがあります。
以前のバージョンのGNUでは、comm
NULとNLを交換できる必要があります。
comm -13 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) |
tr '\n\0' '\0\n'
このアプローチは改行comm
で区切られたレコードでもまだ機能しますが、入力の実際の改行はNULでエンコードされているため、改行を含むファイル名を安全に処理できます。
C
少なくともGNUシステムとほとんどのUTF-8ロケールは同じようにソートされており、ここで問題を引き起こす他の文字列があるため、ロケールをに設定する必要があります。
これは非常に一般的な技術です(参照:リバースマッチライン、NULで区切られた別の例はcomm
)ですが、入力時にNULをサポートするユーティリティが必要です。これはGNUシステムの外部では比較的まれです。
例:
$ touch dir1/{①,②} dir2/{②,③}
$ comm -12 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort)
./③
./②
$ (export LC_ALL=C
comm -12 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort))
./②
(2019年編集: 最新バージョンの GNU libc では、① ② ③ の相対的な順序が修正されていますが、以下を使用できます。