Sự khác biệt về chuỗi Bash


70

Tôi đang cố tìm cách xác định sự khác biệt giữa hai chuỗi trong tập lệnh của mình. Tôi có thể dễ dàng làm điều này với diff hoặc comm, nhưng tôi không giao dịch với các tập tin và tôi không muốn xuất chúng vào các tập tin, làm so sánh và đọc nó trở lại.

Tôi thấy rằng comm, diff, cmp đều cho phép truyền hai tệp HOẶC một tệp và đầu vào tiêu chuẩn - tôi đoán đó là tốt nếu tôi không muốn xuất hai tệp ... nhưng nó vẫn rất tệ.

Được đào tạo xung quanh suy nghĩ tôi có thể sử dụng grep hoặc cụm từ thông dụng - nhưng tôi đoán là không.

Cảm ơn trước,

+1

gì được nó, bạn thực sự muốn làm gì? 18 jan. 092009-01-18 02:51:04

  0

Bạn có thể sử dụng các thao tác chuỗi con và các hoạt động kiểm tra nội bộ với các thay đổi IFS để so sánh, nhưng bạn sẽ cần phải biết nếu bạn muốn so sánh ký tự theo từng ký tự, từng chữ, từng dòng, bỏ qua khoảng trắng ... 21 jul. 122012-07-21 10:33:51

9

Nhắc tôi về câu hỏi này: How can you diff two pipelines in Bash?

Nếu bạn đang ở trong một phiên bash, bạn có thể làm một:

diff <cmd1 <cmd2 
diff <(foo | bar) <(baz | quux) 

với < tạo ống tên vô danh - - được quản lý bởi bash - vì vậy chúng được tạo và tự động bị phá hủy, không giống như các tệp tạm thời.

Vì vậy, nếu bạn quản lý để cô lập hai bạn chuỗi khác nhau như là một phần của một lệnh (grep, awk, sed, ...), bạn có thể làm - ví dụ - một cái gì đó như:

diff < grep string1 myFile < grep string2 myFile 

(nếu bạn cho rằng bạn có trong dây chuyền tập tin của bạn như string1=very_complicated_valuestring2=another_long_and_complicated_value': mà không biết định dạng nội bộ của tập tin của bạn, tôi không thể đề nghị một lệnh chính xác)


124

Sử dụng diff hoặc com hay bất cứ điều gì bạn muốn:

diff <(echo "$string1") <(echo "$string2") 

Greg của Bash FAQ: Process Substitution

hoặc với một ống tên

mkfifo ./p 
diff - p <<< "$string1" & echo "$string2" > p 

Greg của Bash FAQ: Working with Named Pipes

ống đặt tên cũng được biết đến như một FIFO.

Bản thân số - riêng cho đầu vào tiêu chuẩn.

<<< là "chuỗi tại đây".

& là như ; nhưng đặt nó ở chế độ nền

+3

+1 để có câu trả lời đúng. 1 cho lời giải thích tuyệt vời của các biểu tượng. Ngoài ra, các câu hỏi thường gặp của Bash's Bash đã được chuyển đến: http://mywiki.wooledge.org/ Các liên kết dành cho các trang trên hiện có tại http://mywiki.wooledge.org/ProcessSubstitutionhttp://mywiki.wooledge.org/ BashFAQ/085 20 feb. 132013-02-20 17:30:24

  0

thx! và ngoài ra, điều này sẽ hiển thị các mô tả tập tin động 'FUNC() {echo" $ @ "; "$ @"; }; FUNC diff <(echo a) <(echo b); ' 16 apr. 152015-04-16 01:30:54

  0

Tôi đang tìm kiếm điều đó để tổng hợp hai shasums. Không chắc chắn nếu có một cách thanh lịch hơn để làm điều đó, nhưng nó hoạt động. 23 aug. 162016-08-23 08:29:09

  0

Điều này dường như hoạt động nếu có nhiều dòng trong $ string1 và $ string2, và diff xuất ra các dòng đã được cộng hoặc trừ. Điều gì nếu chuỗi là một dòng, và dòng và có một số sự khác biệt giữa hai dây? 10 aug. 172017-08-10 15:28:00


11

tôi thích cmp và Process tính năng Thay thế bash:

$ cmp -bl <(echo -n abcda) <(echo -n aqcde) 
    2 142 b 161 q 
    5 141 a 145 e 

Nói về vị trí thứ 2, ab xảy ra cho những người đầu tiên, nhưng aq cho thứ hai. Ở vị trí thứ 5, một sự khác biệt đang xảy ra. Chỉ cần thay thế các chuỗi đó bằng các biến và bạn đã hoàn thành.

  0

Chỉ hoạt động khi các chuỗi có cùng độ dài! 06 may. 162016-05-06 11:58:04


8

Giả sử bạn có ba chuỗi

a="this is a line" 
b="this is" 
c="a line" 

Để loại bỏ tiền tố b từ một

echo ${a#"$b"} 

Để loại bỏ hậu tố c từ một

echo ${a%"$c"} 
+1

Tôi đoán đây là cách bash làm việc đó. Nó hoạt động rất tốt. Cú pháp đó hơi khó nắm bắt. 05 nov. 142014-11-05 20:39:25

  0

@MikaelRoos Đồng ý. Dễ đọc hơn (đối với tôi anyway) sẽ sử dụng sed: 'echo" $ a "| sed "s!^$ b !! g" '(Tôi hoán đổi bộ tách sed tiêu chuẩn/cho! trong trường hợp các biến được xử lý là các đường dẫn. Ngoài ra, bạn có thể sử dụng một chuỗi ở đây thay vì echo:' sed ... <<< $ a'.) 08 sep. 162016-09-08 18:06:40