Làm thế nào tôi có thể nhận diff để chỉ hiển thị các dòng được thêm và xóa? Nếu diff không thể làm điều đó, công cụ nào có thể?
diff A B | grep '^[<>]'
comm
.
Làm thế nào tôi có thể nhận diff để chỉ hiển thị các dòng được thêm và xóa? Nếu diff không thể làm điều đó, công cụ nào có thể?
diff A B | grep '^[<>]'
comm
.
Câu trả lời:
Một cách khác để xem xét nó:
Hiển thị các dòng chỉ tồn tại trong tệp a: (tức là những gì đã bị xóa khỏi a)
comm -23 a b
Hiển thị các dòng chỉ tồn tại trong tệp b: (tức là những gì đã được thêm vào b)
comm -13 a b
Hiển thị các dòng chỉ tồn tại trong một tệp này hoặc tệp khác: (nhưng không phải cả hai)
comm -3 a b | sed 's/^\t//'
(Cảnh báo: Nếu tệp a
có các dòng bắt đầu bằng TAB, thì nó (TAB đầu tiên) sẽ bị xóa khỏi đầu ra.)
LƯU Ý: Cả hai tệp cần được sắp xếp comm
để hoạt động chính xác. Nếu chúng chưa được sắp xếp, bạn nên sắp xếp chúng:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Nếu các tệp quá dài, đây có thể là một gánh nặng khá lớn vì nó yêu cầu một bản sao thêm và do đó gấp đôi dung lượng đĩa.
comm -12 <(sort a) <(sort b)
comm
có thể làm những gì bạn muốn. Từ trang người đàn ông của nó:
SỰ MIÊU TẢ
So sánh các tệp được sắp xếp FILE1 và FILE2 theo từng dòng.
Không có tùy chọn, sản xuất đầu ra ba cột. Cột một chứa các dòng duy nhất cho FILE1, cột hai chứa các dòng duy nhất cho FILE2 và cột ba chứa các dòng chung cho cả hai tệp.
Các cột này có thể được nén với -1
, -2
và -3
tương ứng.
Thí dụ:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
Và nếu bạn chỉ muốn các dòng duy nhất và không quan tâm đến tập tin nào trong đó:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Như trang man nói, các tập tin phải được sắp xếp trước.
Để hiển thị các bổ sung và xóa mà không có ngữ cảnh, số dòng, +, -, <,>! vv, bạn có thể sử dụng diff như thế này:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Ví dụ: đưa ra hai tệp:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
Lệnh sau sẽ hiển thị các dòng hoặc bị xóa khỏi a hoặc được thêm vào b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
đầu ra:
B-ONLY
A-ONLY
Lệnh hơi khác này sẽ hiển thị các dòng bị xóa khỏi a.txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
đầu ra:
A-ONLY
Cuối cùng, lệnh này sẽ hiển thị các dòng được thêm vào a.txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
đầu ra
B-ONLY
Đó là những gì diff làm theo mặc định ... Có lẽ bạn cần thêm một số cờ để bỏ qua khoảng trắng?
diff -b -B
nên bỏ qua các dòng trống và số lượng không gian khác nhau.
Không, diff
không thực sự cho thấy sự khác biệt giữa hai tệp theo cách người ta có thể nghĩ. Nó tạo ra một chuỗi các lệnh chỉnh sửa cho một công cụ muốn patch
sử dụng để thay đổi một tệp thành một tệp khác.
Khó khăn cho bất kỳ nỗ lực nào trong việc thực hiện những gì bạn đang tìm kiếm là làm thế nào để xác định những gì tạo thành một dòng đã thay đổi so với một dòng bị xóa theo sau là một dòng được thêm vào. Ngoài ra, phải làm gì khi các dòng được thêm, xóa và thay đổi liền kề nhau.
diff
nguồn, nhưng dường như tôi nhớ tất cả các cách điều hướng để theo dõi nơi hai tập tin khớp nhau và tôi nghĩ có một ngưỡng từ bỏ dựa trên khoảng cách xa nhau dòng là. Nhưng tôi không nhớ bất kỳ kết hợp nội dòng nào ngoại trừ (tùy chọn) thu gọn khoảng trắng hoặc bỏ qua trường hợp. Hoặc (có lẽ) từ để ảnh hưởng. Trong mọi trường hợp, đó là tất cả về patch
và "vgrep" chỉ đi cùng cho chuyến đi. Có lẽ. Vào thứ ba.
Các công cụ so sánh trực quan khớp hai tệp với nhau để một phân đoạn có cùng số dòng nhưng nội dung khác nhau sẽ được coi là một phân đoạn đã thay đổi. Các dòng hoàn toàn mới giữa các phân đoạn khớp được coi là các phân đoạn được thêm vào.
Đây cũng là cách công cụ dòng lệnh sdiff hoạt động, cho thấy sự so sánh song song của hai tệp trong một thiết bị đầu cuối. Các dòng thay đổi được phân tách bằng | tính cách. Nếu một dòng chỉ tồn tại trong tệp A, <được sử dụng làm ký tự phân cách. Nếu một dòng chỉ tồn tại trong tệp B,> được sử dụng làm dấu phân cách. Nếu bạn không có <và> ký tự trong tệp, bạn có thể sử dụng ký tự này để chỉ hiển thị các dòng đã thêm:
sdiff A B | grep '[<>]'
Cảm ơn senarvi, giải pháp của bạn (không được bình chọn) thực sự đã cho tôi CHÍNH XÁC những gì tôi muốn sau khi tìm kiếm độ tuổi trên một tấn trang.
Sử dụng câu trả lời của bạn, đây là những gì tôi nghĩ ra để có được danh sách những thứ đã thay đổi / thêm / xóa. Ví dụ này sử dụng 2 phiên bản của tệp / etc / passwd và in tên người dùng cho các bản ghi liên quan.
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
Tôi thấy hình thức đặc biệt này thường hữu ích:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Thí dụ:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Đầu ra:
-b
-c
+B
+C
-e
-f
+E
+F
Vì vậy, nó hiển thị các dòng cũ với -
ngay sau đó là dòng mới tương ứng với +
.
Nếu chúng tôi đã xóa C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
nó trông như thế này:
-b
+B
+C
-e
-f
+E
+F
Các định dạng được ghi lại tại man diff
:
--line-format=LFMT
format all input lines with LFMT`
và:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
và:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Câu hỏi liên quan: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-b between-two-files-in-linux
Đã thử nghiệm trong Ubuntu 18.04.
Tệp1:
text670_1
text067_1
text067_2
Tệp2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Sử dụng:
diff -y file1 file2
Điều này hiển thị hai cột cho các tập tin repectives.
Đầu ra:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1