Cách so sánh từng dòng các tệp trong Linux bằng lệnh diff - Phần II

theanh

Administrator
Nhân viên
Trong phần đầu tiên của loạt bài hướng dẫn về lệnh diff này, chúng ta đã thảo luận về những điều cơ bản của lệnh, bao gồm cách lệnh hoạt động và cách hiểu kết quả đầu ra mà lệnh tạo ra. Mặc dù chắc chắn có một chút đường cong học tập liên quan đến tiện ích dòng lệnh này, nhưng nó rất đáng để học, đặc biệt nếu công việc hàng ngày của bạn liên quan đến việc thực hiện các tác vụ liên quan đến tệp trên máy Linux chỉ có CLI.

Giả sử rằng bạn đã biết cách sử dụng cơ bản của lệnh diff, trong hướng dẫn này, chúng ta sẽ thảo luận về các tùy chọn dòng lệnh khác nhau mà công cụ này cung cấp, thông qua một số ví dụ dễ hiểu.

Nhưng trước khi tiếp tục, hãy nhớ rằng tất cả các ví dụ trong hướng dẫn này đã được thử nghiệm trên Ubuntu 14.04 với Bash phiên bản 4.3.11(1) và diff version3.3.


Tùy chọn lệnh diff​

1. Báo cáo khi các tệp giống hệt nhau​

Theo mặc định, khi lệnh diff phát hiện các tệp đang được so sánh giống hệt nhau, nó sẽ không tạo ra bất kỳ đầu ra nào.
Mã:
$ diff file1 file2
$
Nhưng, có một tùy chọn dòng lệnh (-s) mà bạn có thể sử dụng để buộc lệnh báo cáo điều này trong đầu ra:
Mã:
$ diff -s file1 file2
[B]Các tệp file1 và file2 giống hệt nhau[/b]

2. Ngữ cảnh đã sao chép và Ngữ cảnh hợp nhất​

Về cơ bản, đây là hai định dạng khác nhau mà lệnh diff có thể tạo ra đầu ra của nó. Ngữ cảnh đã sao chép được bật bằng tùy chọn dòng lệnh -c, trong khi Ngữ cảnh hợp nhất được bật bằng tùy chọn -u. Sau đây là ví dụ về ngữ cảnh trước:
Mã:
$ diff -c file1 file2
*** file1 2016-12-29 09:36:47.175597647 +0530
--- file2 2016-12-29 09:19:55.799558326 +0530
***************
*** 1,3 ****
Xin chào
! Xin chào
Tạm biệt
--- 1,3 ----
Xin chào
! Xin chào
Tạm biệt
Vì vậy, trong định dạng đầu ra ngữ cảnh Đã sao chép, các dòng khác nhau được chỉ ra bằng dấu chấm than (!).

Và đây là ví dụ về định dạng ngữ cảnh Thống nhất:
Mã:
$ diff -u file1 file2
--- file1 2016-12-29 09:36:47.175597647 +0530
+++ file2 2016-12-29 09:19:55.799558326 +0530
@@ -1,3 +1,3 @@
Xin chào
-Xin chào
+Xin chào
Tạm biệt
Trong định dạng đầu ra này, +-các ký hiệu trước các dòng biểu thị các phiên bản của dòng khác nhau :'-'khi dòng trong tệp1 bị thiếu trong tệp2, '+' khi dòng trong tệp2 được thêm vào tệp1.


3. Đầu ra một tập lệnh 'ed'​

Lệnh diff cũng có khả năng tạo ra các lệnh mà trình soạn thảo 'ed' có thể sử dụng để chuyển đổi tệp gốc (file1 trong các ví dụ của chúng tôi tại đây) thành tệp mới (file2). Sau đây là cách bạn thực hiện điều này:

Giả sử file1 và file2 chứa thay đổi sau:
Mã:
$ diff file1 file2
2c2
< Hellolo
---
> Hello
Bây giờ, hãy sử dụng tùy chọn dòng lệnh -e để tạo đầu ra mà trình soạn thảo 'ed' hiểu được và chuyển hướng đầu ra đó vào một tệp:
Mã:
diff -e file1 file2 > out
Sau đây là những gì out chứa trong trường hợp này:
Mã:
2c
Hello
.
Tiếp theo, bạn cần thêm lệnh 'w' vào cuối tệp out.
Mã:
2c
Hello
.
[B]w[/b]
Bây giờ, hãy chạy lệnh sau:
Mã:
ed - file1 < out
Và bạn sẽ thấy file1 và file2 bây giờ giống hệt nhau.
Mã:
$ diff file1 file2
$
Để biết thêm thông tin về chức năng này, hãy truy cập đây.


4. Tạo đầu ra trong hai cột​

Thông thường, lệnh diff tạo đầu ra theo cách sau:
Mã:
$ diff file1 file2
2c2
< Hello
---
> Hello
Nhưng có một tùy chọn dòng lệnh (-y) chỉ đạo diff tạo đầu ra trong hai cột riêng biệt. Sau đây là một ví dụ:
Mã:
$ diff -y file1 file2
Xin chào Xin chào
Xin chào | Xin chào
Tạm biệt
Như bạn thấy, định dạng đầu ra này sử dụng '|' để chỉ các dòng khác nhau.


5. Ẩn các dòng chung​

Nếu bạn quan sát đầu ra được hiển thị trong phần trước (điểm 4 ở trên), bạn sẽ nhận thấy rằng với tùy chọn dòng lệnh -y, diff - trong đầu ra - cũng tạo ra các dòng chung. Trong trường hợp bạn cần loại bỏ các dòng giống hệt nhau này, bạn có thể sử dụng tùy chọn --suppress-common-lines.
Mã:
himanshu@himanshu-desktop:~$ diff -y --suppress-common-lines file1 file2
Xin chào | Xin chào

6. Hiển thị hàm C mỗi thay đổi nằm trong​

Đối với những trường hợp bạn sử dụng diff để so sánh hai tệp ngôn ngữ C, có một tùy chọn dòng lệnh (-p) hướng dẫn tiện ích hiển thị chính xác hàm C nào mỗi thay đổi nằm trong. Ví dụ, giả sử đây là hai tệp C:

file1.c:
Mã:
#include

void compare(float x, float y)
{
 if(x == y) // cách không chính xác
 {
 printf("\n EQUAL \n");
 }
}


int main(void)
{
 compare(1.234, 1.56789);

 return 0;
}
file2.c:
Mã:
#include

void compare(float x, float y)
{
 if(x == y)
 {
 printf("\n EQUAL \n");
 }
}


int main(void)
{
 compare(1.234, 1.56789);

 return 0;
}
Đây là kết quả khi cả hai tệp được so sánh bình thường:
Mã:
$ diff file1.c file2.c 
5c5
< if(x == y) // cách không đúng
---
> if(x == y)
Và đây là kết quả khi các tệp được so sánh bằng tùy chọn -p:
Mã:
$ diff -p file1.c file2.c 
*** file1.c 2016-12-29 11:45:36.587010816 +0530
--- file2.c 2016-12-29 11:46:39.823013274 +0530
***************
*** 2,8 ****
 
void compare(float x, float y)
{
! if(x == y) // cách không đúng
{
printf("\n EQUAL \n");
}
--- 2,8 ----
 
void compare(float x, float y)
{
! if(x == y)
{
printf("\n EQUAL \n");
}
Như bạn thấy, với -p, diff cung cấp cho bạn cái nhìn chi tiết hơn về nơi thay đổi, chỉ ra các dòng khác nhau bằng dấu chấm than (!).


7. So sánh đệ quy các thư mục con​

Lệnh diff cũng cho phép bạn so sánh đệ quy các thư mục con, nhưng đó không phải là hành vi mặc định của nó. Ý tôi muốn nói là, nếu bạn lấy trường hợp sau:
Mã:
$ diff diff-files/ second-diff-files/
diff diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello
Lệnh diff chỉ so sánh các tệp trong các thư mục cấp cao nhất, nhưng nếu bạn sử dụng tùy chọn dòng lệnh -r (dành cho diff đệ quy), bạn sẽ thấy rằng ngay cả các tệp có trong các thư mục con cũng được so sánh:
Mã:
$ diff -r diff-files/ second-diff-files/
diff -r diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff -r diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello
[B]diff -r diff-files/more-diff-files/file1 second-diff-files/more-diff-files/file1[/b]
1c1
< Xin chào
---
> i
[B]diff -r diff-files/more-diff-files/file2 second-diff-files/more-diff-files/file2[/b]
2c2
< Xin chào
---
> ello

8. Xử lý các tệp vắng mặt như là rỗng​

Lệnh diff cũng cung cấp một tùy chọn mà bạn có thể sử dụng để chỉ đạo công cụ xử lý các tệp vắng mặt như là rỗng. Ví dụ, nếu bạn so sánh file1 với file3 (không tồn tại), hành vi mặc định của diff là tạo ra lỗi:
Mã:
$ diff file1 file3
diff: file3: No such file or directory
Điều này không sai; trên thực tế, điều này hoàn toàn hợp lý. Nhưng có thể có những trường hợp mà bạn không muốn lệnh diff trả về lỗi cho những tình huống như vậy (mặc dù là một phần của tập lệnh bash, có thể chứ?), thì đối với những tình huống đó, bạn có thể sử dụng tùy chọn dòng lệnh -N buộc lệnh coi các tệp vắng mặt là rỗng và tiếp tục so sánh.
Mã:
$ diff -N file1 file3
1,5d0
< Hi
< 
< Hellolo
< 
< Bye

Kết luận​

Nếu bạn thực hiện đúng cả hai phần của loạt bài hướng dẫn này và thực hành tất cả các ví dụ có trong bài viết, thì có thể nói rằng bạn sẽ có thể sử dụng thành thạo công cụ này. Tất nhiên, chúng tôi không thể thảo luận mọi thứ liên quan đến diff trong loạt bài này, nhưng hãy yên tâm rằng nhiều tính năng/chức năng quan trọng đã được đề cập.

Đối với những ai muốn biết thêm về tiện ích, trang hướng dẫnluôn ở đó dành cho bạn. Và chưa kể đến việc bạn nên thường xuyên sử dụng công cụ này với các tập tin khác nhau để mô phỏng các trường hợp sử dụng khác nhau.
 
Back
Bên trên