私は2つのファイルを持っています:
oldlist
-これには、ファイルのリストと各ファイルのmd5ハッシュが含まれます。これは1年前に生成されました。newlist
-これには、ファイルのリストと各ファイルのmd5ハッシュも含まれます。ただし、一部のファイルが変更され(たとえば、md5ハッシュが異なる)、いくつかの新しいファイルが追加されました。oldlist
とnewlist
のすべての違いを確認したいのですが、oldlist
に存在しないファイルはすべて無視したいと思います。
つまり、新しいファイルは気にしません。古いファイルごとにmd5ハッシュを比較するだけで、昨年中にファイルが変更されたかどうかを確認できます。
join
を使用して、2つのファイルの一致する行を結合します。ファイル名がチェックサムの後にあり(md5sum
出力のように)、空白が含まれていないとすると、両方のリストに存在するすべてのファイル名が、古いチェックサムと新しいチェックサムとともに出力されます。
join -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist)
新しいファイルも表示するには、-a
オプションをjoin
に渡します。出力の後処理を少し行うと、チェックサムが変更されていないファイル名が削除されます。
join -a 2 -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist) |
awk '$2 != $3'
awk
だけでそれを行うことができます:
$ awk 'FNR==NR { o[$2]=$1; next } !o[$2] { print $0, "NEW"; next }
$1!=o[$2] { print $0, "CHANGED" }' newlist oldlist
(ファイルの想定される形式はmd5sum
の出力形式: "md5filename"であることに注意してください。)
更新:そのawk
ワンライナーがどのように機能するかを段階的に説明します。
awk 'FNR==NR { # if current record number==overall record number (still processing the first file)
o[$2]=$1 # store the record in array o: the key is the file name, the value is the md5
next # go to next record (do not execute the rest of the code)
}
# reaching this point means we are processing the second input file
!o[$2] { # if array o not contains item with the current record`s file name
print $0, "NEW" # print the current record and specify that it`s new
next # go to next record (do not execute the rest of the code)
}
# reaching this point means array o contains item with the current file name
$1!=o[$2] { # if the current md5 is not equal with the md5 save for the current file name
print $0, "CHANGED" # print the current record and specify it`s changed
}' newlist oldlist
私があなたの質問を正しく理解していれば、comm
は確かにあなたが望むことをすることができます。 comm --help
を調べることをお勧めします
具体的には
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
したがって、comm newFile oldFile -1 -3
はあなたが望むことをします。
別の方法として、ファイルまたはmd5sumのリストを比較するために常に「_sdiff -s
_」を使用しました。
ファイルが通常のmd5sum出力 "_md5hash filename
_"であると仮定します。次に、次のいずれかを行います。
_sdiff -s oldfile newfile | grep -v ">"
# sorting on the md5hash should help align and pick up renamed files.
sdiff -s <(sort oldfile) <(sort newfile)
_
これを分解する:
_sdiff -s
_:共通行を抑制するため、完全一致は無視されます。違いについては、_|
_、_<
_、_>
_を表示します。<(sort oldfile)
:コマンドはsdiffの前にソートします。
_grep -v ">"
_:新しいファイルエントリを無視します。ファイル名に_>
_が含まれていない場合にのみ機能しますが、これはとにかくありそうにありません。
sdiff
の幅を変更して、より長い行を表示することができます_-w 100
_。
ファイルが(スペースで区切られた)次のようになっているとします。
file1 md5sum1
file2 md5sum2
簡単な解決策:
# get only the files:
cut -f 1 -d " " oldlist > oldlist.files
# from newlist, take only files which were also in the oldlist (updated files)
grep -w -F -f oldlist.files newlist > newlist.updated_files
そして、2つのファイルを比較することができます(並べ替え後):
sort -u oldlist > oldlist.su
sort -u newlist.updated_files > newlist.updated_files.su
diff oldlist.su newlist.updated_files.su