So sánh một tệp cũ và tệp mới, nhưng bỏ qua các dòng chỉ tồn tại trong tệp mới?


7

Tôi có hai tệp:

  1. oldlist- Phần này chứa danh sách các tệp và hàm băm md5 cho mỗi tệp. Điều này đã được tạo ra một năm trước.
  2. newlist- Điều này cũng chứa danh sách các tệp và hàm băm md5 cho mỗi tệp. Tuy nhiên, một số tệp đã được thay đổi (ví dụ: băm md5 của chúng là khác nhau) và một số tệp mới đã được thêm vào.

Tôi muốn thấy tất cả sự khác biệt giữa oldlistnewlist, nhưng tôi muốn bỏ qua bất kỳ tệp nào không tồn tại oldlist.

Đó là, tôi không quan tâm đến các tập tin mới. Tôi chỉ muốn so sánh băm md5 cho mỗi tệp cũ, để tôi có thể xem liệu có tệp nào đã thay đổi trong năm ngoái không.

Tôi đã thử diffcomm , nhưng chưa tìm được giải pháp.

Câu trả lời:


5

Sử dụng joinđể kết hợp các dòng khớp từ hai tệp. Giả sử tên tệp xuất hiện sau tổng kiểm tra (như ở md5sumđầu ra) và không chứa khoảng trắng, điều này sẽ in tất cả các tên tệp có trong cả hai danh sách, cùng với tổng kiểm tra cũ và tổng kiểm tra mới:

join -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist)

Để xem các tập tin mới, chuyển -atùy chọn đến join. Một chút xử lý hậu kỳ đầu ra sẽ xóa tên tệp mà tổng kiểm tra không thay đổi.

join -a 2 -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist) |
awk '$2 != $3'

3

Bạn có thể làm điều đó với awkmột mình:

$ awk 'FNR==NR   { o[$2]=$1; next }       !o[$2] { print $0, "NEW"; next } 
       $1!=o[$2] { print $0, "CHANGED" }' newlist oldlist

(Lưu ý rằng định dạng được cho là của các tệp là md5sumđịnh dạng đầu ra: "tên tệp md5".)

Cập nhật : giải thích từng bước về cách thức awkhoạt động của một lớp lót.

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

Câu trả lời hay, bạn có phiền khi thêm một lời giải thích nhỏ về chương trình awk không? Ví dụ: FNR == NR bảo vệ hành động áp dụng cho tệp thứ 2, v.v.
maxschlepzig

@maxschlepzig, tôi đã thêm lời giải thích. Trong trường hợp nó không đáp ứng các tiêu chuẩn SO và kỳ vọng, tôi sẵn sàng cho các đề xuất để cập nhật nó.
manatwork

3

Nếu tôi hiểu chính xác câu hỏi của bạn thì commthực sự có thể làm những gì bạn muốn. Tôi đề nghị xem xétcomm --help

cụ thể

  -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)

vì vậy comm newFile oldFile -1 -3sẽ làm những gì bạn muốn.


1

Giả sử các tệp trông giống như (không gian được phân tách):

file1 md5sum1
file2 md5sum2

Giải pháp đơn giản:

# 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

Và sau đó bạn chỉ có thể so sánh hai tệp (sau khi sắp xếp):

sort -u oldlist > oldlist.su
sort -u newlist.updated_files > newlist.updated_files.su
diff oldlist.su newlist.updated_files.su

1

Chỉ để thay thế, tôi đã luôn sử dụng " sdiff -s" để so sánh danh sách các tệp hoặc md5sums.

Giả sử các tệp là đầu ra md5sum bình thường " md5hash filename". Sau đó, một trong hai:

sdiff -s oldfile newfile | grep -v ">"
# sorting on the md5hash should help align and pick up renamed files.
sdiff -s <(sort oldfile) <(sort newfile)

Phá vỡ điều này :: thay thế
sdiff -scác dòng chung, vì vậy các kết quả khớp chính xác bị bỏ qua. Chương trình |, <, >cho sự khác biệt.
<(sort oldfile): thực hiện lệnh sắp xếp trước sdiff.
grep -v ">": Bỏ qua các mục mới. Chỉ hoạt động nếu bạn không có >tên tập tin, điều này không thể xảy ra.

Chiều rộng của sdiffcó thể được thay đổi để hiển thị các dòng dài hơn -w 100.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.