2つのディレクトリを再帰的に比較し、異なるもののファイル名onlyを出力するLinuxコマンドを実行しようとしています。これには、1つのディレクトリに存在し、他のディレクトリには存在しない、またはその逆、およびテキストの違いが含まれます。
Diffのマニュアルページから:
-q
filesファイルが異なるかどうかのみを報告し、差異の詳細は報告しません。-r
directoriesディレクトリを比較するとき、見つかったサブディレクトリを再帰的に比較します。
コマンド例:
diff -qr dir1 dir2
出力例(ロケールに依存):
$ ls dir1 dir2
dir1:
same-file different only-1
dir2:
same-file different only-2
$ diff -qr dir1 dir2
Files dir1/different and dir2/different differ
Only in dir1: only-1
Only in dir2: only-2
Rsyncを使用することもできます
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
1つのディレクトリにのみあり、サブディレクトリではなくファイル名のみのファイルのリストを取得する場合:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
完全なパスで異なるすべてのファイルとディレクトリを再帰的に一覧表示する場合:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
これにより、すべてのファイルに異なるコマンドを適用できます。
たとえば、dir1にあるがdir2にはないすべてのファイルとディレクトリを削除できます。
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
diff -qr old/ new/
を実行するアプローチには1つの大きな欠点があります。新しく作成されたディレクトリ内のファイルを見逃す可能性があります。例えば。以下の例では、ファイルdata/pages/playground/playground.txt
はdiff -qr old/ new/
の出力にはありませんが、ディレクトリdata/pages/playground/
は(ブラウザーでplayground.txtを検索してすばやく比較します) 。また、次のソリューションも投稿しました nixおよびLinux Stack Exchangeで ですが、ここにもコピーします。
プログラムで新しいファイルまたは変更されたファイルのリストを作成するには、rsync、sortを使用するのが最善の解決策です、およびuniq:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
この例を使用して説明します。2つのdokuwikiリリースを比較して、変更されたファイルと新しく作成されたファイルを確認します。
Wgetでtarを取得し、それらをold/
およびnew/
ディレクトリに抽出します。
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
Rsyncとdiffの比較がここに示されているように、rsyncを一方向に実行すると、新しく作成されたファイルを見逃す場合があります。
rsync -rcn --out-format="%n" old/ new/
次の出力が得られます:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
Rsyncを一方向でのみ実行すると、新しく作成されたファイルが失われ、逆方向では削除されたファイルが失われます。diffの出力を比較してください。
diff -qr old/ new/
次の出力が得られます:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
両方の方法でrsyncを実行し、出力をソートして重複を削除すると、最初にディレクトリdata/pages/playground/
とファイルdata/pages/playground/playground.txt
が失われたことがわかります。
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
次の出力が得られます:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
は次の引数で実行されます。
-r
を「ディレクトリに再帰」し、-c
は、同じサイズのファイルを比較し、「mod-timeとsizeではなくチェックサムに基づいてスキップする」だけです。-n
から「変更を加えずに試運転を実行する」、および--out-format="%n"
を「指定されたFORMATを使用して更新を出力する」、これはファイル名のみの場合は「%n」ですrsync
の両方向の出力(ファイルのリスト)はsort
を使用して結合およびソートされ、uniq
ですべての重複を削除することにより、このソートされたリストが圧縮されます。
Linuxシステムでjustファイル名を取得するには
diff -q /dir1 /dir2|cut -f2 -d' '