web-dev-qa-db-ja.com

古いファイルと新しいファイルを比較しますが、新しいファイルにのみ存在する行を無視しますか?

私は2つのファイルを持っています:

  1. oldlist-これには、ファイルのリストと各ファイルのmd5ハッシュが含まれます。これは1年前に生成されました。
  2. newlist-これには、ファイルのリストと各ファイルのmd5ハッシュも含まれます。ただし、一部のファイルが変更され(たとえば、md5ハッシュが異なる)、いくつかの新しいファイルが追加されました。

oldlistnewlistのすべての違いを確認したいのですが、oldlistに存在しないファイルはすべて無視したいと思います。

つまり、新しいファイルは気にしません。古いファイルごとにmd5ハッシュを比較するだけで、昨年中にファイルが変更されたかどうかを確認できます。

diffcomm を試しましたが、まだ解決策が見つかりません。

7

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
3
manatwork

私があなたの質問を正しく理解していれば、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はあなたが望むことをします。

3
Sirex

別の方法として、ファイルまたは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_。

1
Matt

ファイルが(スペースで区切られた)次のようになっているとします。

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
1
Tomas