Cách so sánh hai tập tin


83

Vì vậy, về cơ bản những gì tôi muốn làm là so sánh hai tệp theo từng dòng 2. Làm thế nào tôi có thể thực hiện được điều này?

Tệp_1.txt:

User1 US
User2 US
User3 US

Tệp_2.txt:

User1 US
User2 US
User3 NG

Kết quả đầu ra:

User3 has changed

11
Sử dụngdiff "File_1.txt" "File_2.txt"
Pandya

Đồng thời truy cập: Askubfox.com/q/12473
Pandya

Câu trả lời:


92

Nhìn vào diffmệnh lệnh. Đây là một công cụ tốt và bạn có thể đọc tất cả về nó bằng cách nhập man diffvào thiết bị đầu cuối của bạn.

Lệnh bạn sẽ muốn làm là diff File_1.txt File_2.txtsẽ tạo ra sự khác biệt giữa hai và sẽ trông giống như thế này:

nhập mô tả hình ảnh ở đây

Lưu ý nhanh về việc đọc đầu ra từ lệnh thứ ba: 'Mũi tên' ( <>) đề cập đến giá trị của dòng trong tệp bên trái ( <) so với tệp bên phải ( >), với tệp bên trái là tệp bạn đã nhập đầu tiên trên dòng lệnh, trong trường hợp nàyFile_1.txt

Ngoài ra, bạn có thể nhận thấy lệnh thứ 4 là diff ... | tee Output_Fileđiều này dẫn các kết quả từ diffmột tee, sau đó đưa đầu ra đó vào một tệp, để bạn có thể lưu nó sau này nếu bạn không muốn xem tất cả trên bàn điều khiển ngay lúc đó.


Điều này có thể làm các tập tin khác (như hình ảnh)? Hoặc nó chỉ giới hạn trong các tài liệu?
Opera Opera

2
Theo tôi biết, nó giới hạn ở các tệp văn bản. Mã sẽ hoạt động, vì về cơ bản nó là văn bản, nhưng bất kỳ tệp nhị phân nào (có hình ảnh) sẽ bị loại bỏ. Bạn CÓ THỂ so sánh để xem nếu chúng giống hệt nhau bằng cách làm : diff file1 file2 -s. Dưới đây là một ví dụ: imgur.com/ShrQx9x
Mitch

Có cách nào để tô màu đầu ra? Tôi muốn giữ nó chỉ CLI, nhưng với một số ... cảm ứng của con người.
Lazar Ljubenović

36

Hoặc bạn có thể sử dụng Meld Diff

Meld giúp bạn so sánh các tập tin, thư mục và các dự án được kiểm soát phiên bản. Nó cung cấp so sánh hai và ba chiều của cả tệp và thư mục và có hỗ trợ cho nhiều hệ thống kiểm soát phiên bản phổ biến.

Cài đặt bằng cách chạy:

sudo apt-get install meld

Ví dụ của bạn:

nhập mô tả hình ảnh ở đây

So sánh thư mục:

nhập mô tả hình ảnh ở đây

Ví dụ với đầy đủ văn bản:

nhập mô tả hình ảnh ở đây


18

Bạn có thể sử dụng vimdiff .

Thí dụ:

vimdiff  file1  file2

1
cái này có màu
Jake Toronto

Điều này giúp tôi vì nó cho thấy dòng kết thúc tập tin đầu tiên của tôi là dosvà thứ hai trong unix.
LoMaPh

13

FWIW, tôi thích những gì tôi nhận được với đầu ra song song từ diff

diff -y -W 120 File_1.txt File_2.txt

sẽ cung cấp một cái gì đó như:

User1 US                            User1 US
User2 US                            User2 US
User3 US                          | User3 NG

10

Bạn có thể sử dụng lệnh cmp:

cmp -b "File_1.txt" "File_2.txt"

đầu ra sẽ là

a b differ: byte 25, line 3 is 125 U 116 N

cmpnhanh hơn nhiều so với diffnếu tất cả những gì bạn muốn là mã trả về.
stevesliva

8

Meldlà một công cụ thực sự tuyệt vời. Nhưng bạn cũng có thể sử dụng diffuseđể so sánh trực quan hai tệp:

diffuse file1.txt file2.txt

nhập mô tả hình ảnh ở đây


7

Litteraly dính vào câu hỏi (file1, file2, outputfile với thông báo "đã thay đổi") đoạn script bên dưới hoạt động.

Sao chép tập lệnh vào một tập tin trống, lưu nó dưới dạng compare.py, làm cho nó có thể thực thi được, chạy nó bằng lệnh:

/path/to/compare.py <file1> <file2> <outputfile>

Kịch bản:

#!/usr/bin/env python

import sys
file1 = sys.argv[1]; file2 = sys.argv[2]; outfile = sys.argv[3]

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

with open(outfile, "wt") as out:
    for line in mismatch:
        out.write(line+" has changed"+"\n")

Với một vài dòng bổ sung, bạn có thể làm cho nó in ra tệp đầu ra hoặc tới thiết bị đầu cuối, tùy thuộc vào việc tệp đầu ra được xác định:

Để in thành tập tin:

/path/to/compare.py <file1> <file2> <outputfile>

Để in ra cửa sổ terminal:

/path/to/compare.py <file1> <file2> 

Kịch bản:

#!/usr/bin/env python

import sys

file1 = sys.argv[1]; file2 = sys.argv[2]
try:
    outfile = sys.argv[3]
except IndexError:
    outfile = None

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

if outfile != None:
        with open(outfile, "wt") as out:
            for line in mismatch:
                out.write(line+" has changed"+"\n")
else:
    for line in mismatch:
        print line+" has changed"

4

Một cách dễ dàng là sử dụng colordiff, nó hoạt động như thế diffnhưng tô màu đầu ra của nó. Điều này rất hữu ích cho việc đọc khác biệt. Sử dụng ví dụ của bạn,

$ colordiff -u File_1.txt File_2.txt
--- File_1.txt  2016-12-24 17:59:17.409490554 -0500
+++ File_2.txt  2016-12-24 18:00:06.666719659 -0500
@@ -1,3 +1,3 @@
 User1 US
 User2 US
-User3 US
+User3 NG

trong đó utùy chọn cho một sự khác biệt thống nhất. Đây là cách diff khác màu trông như thế nào:

nhập mô tả hình ảnh ở đây

Cài đặt colordiffbằng cách chạy sudo apt-get install colordiff.


1
Nếu bạn muốn màu sắc, tôi thấy diff được tích hợp vào vim thực sự dễ sử dụng, như trong câu trả lời của Mr.S
thomasrutter

2

Câu trả lời bổ sung

Nếu không cần biết phần nào của tệp khác nhau, bạn có thể sử dụng tổng kiểm tra của tệp. Có nhiều cách để làm điều đó, sử dụng md5sumhoặc sha256sum. Về cơ bản, mỗi người trong số họ đưa ra một chuỗi mà nội dung tệp băm. Nếu hai tệp giống nhau, hàm băm của chúng cũng sẽ giống nhau. Điều này thường được sử dụng khi bạn tải xuống phần mềm, chẳng hạn như hình ảnh iso cài đặt Ubuntu. Chúng thường được sử dụng để xác minh tính toàn vẹn của nội dung được tải xuống.

Xem xét tập lệnh bên dưới, nơi bạn có thể đưa ra hai tệp làm đối số và tệp sẽ cho bạn biết liệu chúng có giống nhau hay không.

#!/bin/bash

# Check if both files exist  
if ! [ -e "$1"  ];
then
    printf "%s doesn't exist\n" "$1"
    exit 2
elif ! [ -e "$2" ]
then
    printf "%s doesn't exist\n" "$2"
    exit 2
fi

# Get checksums of eithe file
file1_sha=$( sha256sum "$1" | awk '{print $1}')
file2_sha=$( sha256sum "$2" | awk '{print $1}')

# Compare the checksums
if [ "x$file1_sha" = "x$file2_sha" ]
then
    printf "Files %s and %s are the same\n" "$1" "$2"
    exit 0
else
    printf "Files %s and %s are different\n" "$1" "$2"
    exit 1
fi

Chạy mẫu:

$ ./compare_files.sh /etc/passwd ./passwd_copy.txt                                                                
Files /etc/passwd and ./passwd_copy.txt are the same
$ echo $?
0
$ ./compare_files.sh /etc/passwd /etc/default/grub                                                                
Files /etc/passwd and /etc/default/grub are different
$ echo $?
1

Câu trả lời cũ hơn

Ngoài ra, còn có commlệnh so sánh hai tệp được sắp xếp và đưa ra kết quả trong 3 colums: cột 1 cho các mục duy nhất cho tệp # 1, cột 2 cho các mục duy nhất cho tệp # 2 và cột 3 cho các mục có trong cả hai tệp.

Để chặn một trong hai cột, bạn có thể sử dụng các công tắc -1, -2 và -3. Sử dụng -3 sẽ hiển thị các dòng khác nhau.

Dưới đây bạn có thể thấy ảnh chụp màn hình của lệnh đang hoạt động.

nhập mô tả hình ảnh ở đây

Chỉ có một yêu cầu - các tệp phải được sắp xếp để chúng được so sánh đúng. sortlệnh có thể được sử dụng cho mục đích đó. Bellow là một ảnh chụp màn hình khác, nơi các tệp được sắp xếp và sau đó so sánh. Các dòng bắt đầu ở bên trái chỉ đến File_1, các dòng bắt đầu trên cột 2 chỉ thuộc về File_2

nhập mô tả hình ảnh ở đây


@DavidFoerster thật khó để chỉnh sửa trên thiết bị di động :) Mặc dù vậy, thực hiện ngay bây giờ
Sergiy Kolodyazhnyy

2

Cài đặt git và sử dụng

$ git diff filename1 filename2

Và bạn sẽ nhận được đầu ra ở định dạng màu đẹp

Cài đặt Git

$ apt-get update
$ apt-get install git-core

2

colcmp.sh

So sánh các cặp tên / giá trị trong 2 tệp ở định dạng name value\n. Viết nameđến Output_filenếu thay đổi. Yêu cầu bash v4 + cho các mảng kết hợp .

Sử dụng

$ ./colcmp.sh File_1.txt File_2.txt
User3 changed from 'US' to 'NG'
no change: User1,User2

Kết quả đầu ra

$ cat Output_File
User3 has changed

Nguồn (colcmp.sh)

cmp -s "$1" "$2"
case "$?" in
    0)
        echo "" > Output_File
        echo "files are identical"
        ;;
    1)
        echo "" > Output_File
        cp "$1" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.array1.tmp.sh
        chmod 755 ~/.colcmp.array1.tmp.sh
        declare -A A1
        source ~/.colcmp.array1.tmp.sh

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

        USERSWHODIDNOTCHANGE=
        for i in "${!A1[@]}"; do
            if [ "${A2[$i]+x}" = "" ]; then
                echo "$i was removed"
                echo "$i has changed" > Output_File
            fi
        done
        for i in "${!A2[@]}"; do
            if [ "${A1[$i]+x}" = "" ]; then
                echo "$i was added as '${A2[$i]}'"
                echo "$i has changed" > Output_File
            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then
                echo "$i changed from '${A1[$i]}' to '${A2[$i]}'"
                echo "$i has changed" > Output_File
            else
                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"
            fi
        done
        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
        ;;
    *)
        echo "error: file not found, access denied, etc..."
        echo "usage: ./colcmp.sh File_1.txt File_2.txt"
        ;;
esac

Giải trình

Phân tích mã và ý nghĩa của nó, theo sự hiểu biết tốt nhất của tôi. Tôi hoan nghênh các chỉnh sửa và đề xuất.

So sánh tệp cơ bản

cmp -s "$1" "$2"
case "$?" in
    0)
        # match
        ;;
    1)
        # compare
        ;;
    *)
        # error
        ;;
esac

cmp sẽ đặt giá trị của $? như sau :

  • 0 = khớp tệp
  • 1 = tập tin khác nhau
  • 2 = lỗi

Tôi đã chọn sử dụng một trường hợp .. tuyên bố esac để đánh giá $? giá trị của $? thay đổi sau mỗi lệnh, bao gồm kiểm tra ([).

Ngoài ra, tôi có thể sử dụng một biến để giữ giá trị $? :

cmp -s "$1" "$2"
CMPRESULT=$?
if [ $CMPRESULT -eq 0 ]; then
    # match
elif [ $CMPRESULT -eq 1 ]; then
    # compare
else
    # error
fi

Ở trên làm điều tương tự như tuyên bố trường hợp. IDK mà tôi thích hơn.

Xóa đầu ra

        echo "" > Output_File

Ở trên xóa tệp đầu ra để nếu không có người dùng thay đổi, tệp đầu ra sẽ trống.

Tôi thực hiện điều này bên trong các báo cáo trường hợp để Output_file không thay đổi do lỗi.

Sao chép tệp người dùng vào Shell Script

        cp "$1" ~/.colcmp.arrays.tmp.sh

Trên bản sao File_1.txt vào thư mục nhà hiện tại của người dùng.

Ví dụ: nếu người dùng hiện tại là john, thì ở trên sẽ giống như cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh

Thoát nhân vật đặc biệt

Về cơ bản, tôi bị hoang tưởng. Tôi biết rằng các ký tự này có thể có ý nghĩa đặc biệt hoặc thực thi chương trình bên ngoài khi chạy trong tập lệnh như là một phần của phép gán biến:

  • `- back-tick - thực thi một chương trình và đầu ra như thể đầu ra là một phần của tập lệnh của bạn
  • $ - ký hiệu đô la - thường có tiền tố một biến
  • $ {} - cho phép thay thế biến phức tạp hơn
  • $ () - idk những gì nó làm nhưng tôi nghĩ nó có thể thực thi mã

Những gì tôi không biết là tôi không biết bao nhiêu về bash. Tôi không biết những nhân vật khác có thể có ý nghĩa đặc biệt gì, nhưng tôi muốn thoát khỏi tất cả chúng bằng dấu gạch chéo ngược:

        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh

sed có thể làm nhiều hơn so với khớp mẫu biểu thức thông thường . Mẫu tập lệnh "s / (find) / (thay thế) /" đặc biệt thực hiện khớp mẫu.

"s / (tìm) / (thay thế) / (sửa đổi)"

bằng tiếng Anh: nắm bắt bất kỳ dấu câu hoặc ký tự đặc biệt nào trong nhóm caputure 1 (\\ 1)

  • (thay thế) = \\\\\\ 1
    • \\\\ = ký tự bằng chữ (\\) tức là dấu gạch chéo ngược
    • \\ 1 = chụp nhóm 1

trong tiếng Anh: tiền tố tất cả các ký tự đặc biệt có dấu gạch chéo ngược

  • (bổ nghĩa) = g
    • g = thay thế toàn cầu

trong tiếng Anh: nếu tìm thấy nhiều hơn một trận đấu trên cùng một dòng, thay thế tất cả chúng

Nhận xét toàn bộ Script

        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.arrays.tmp.sh

Ở trên sử dụng một biểu thức chính quy để tiền tố mỗi dòng ~ / .colcmp.arrays.tmp.sh với một ký tự nhận xét bash ( # ). Tôi làm điều này bởi vì sau này tôi có ý định thực thi ~ / .colcmp.arrays.tmp.sh bằng cách sử dụng lệnh nguồn và vì tôi không biết chắc chắn toàn bộ định dạng của File_1.txt .

Tôi không muốn vô tình thực thi mã tùy ý. Tôi không nghĩ có ai làm thế.

"s / (tìm) / (thay thế) /"

bằng tiếng Anh: chụp từng dòng dưới dạng nhóm caputure 1 (\\ 1)

  • (thay thế) = # \\ 1
    • # = ký tự chữ (#) tức là ký hiệu pound hoặc hàm băm
    • \\ 1 = chụp nhóm 1

trong tiếng Anh: thay thế mỗi dòng bằng ký hiệu pound theo sau là dòng được thay thế

Chuyển đổi giá trị người dùng thành A1 [Người dùng] = "giá trị"

        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.arrays.tmp.sh

Trên đây là cốt lõi của kịch bản này.

  • chuyển đổi này: #User1 US
    • đến đây: A1[User1]="US"
    • hoặc này: A2[User1]="US"(cho tệp thứ 2)

"s / (tìm) / (thay thế) /"

bằng tiếng Anh:

  • yêu cầu nhưng bỏ qua các ký tự nhận xét hàng đầu (#)
  • bỏ qua khoảng trắng hàng đầu
  • nắm bắt từ đầu tiên dưới dạng nhóm caputure 1 (\\ 1)
  • yêu cầu một khoảng trắng (hoặc tab hoặc khoảng trắng)
    • nó sẽ được thay thế bằng dấu bằng vì
    • nó không phải là một phần của bất kỳ nhóm bắt giữ nào, và bởi vì
    • mẫu (thay thế) đặt dấu bằng giữa nhóm chụp 1 và nhóm chụp 2
  • bắt phần còn lại của dòng là bắt nhóm 2

  • (thay thế) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"

    • A1 \\ [- ký tự bằng chữ A1[để bắt đầu gán mảng trong một mảng được gọi làA1
    • \\ 1 = nhóm chụp 1 - không bao gồm hàm băm hàng đầu (#) và không bao gồm khoảng trắng hàng đầu - trong trường hợp này, nhóm chụp 1 đang được sử dụng để đặt tên của cặp tên / giá trị trong mảng kết hợp bash.
    • \\] = \ "= ký tự bằng chữ ]="
      • ]= đóng mảng gán, ví dụ A1[User1 ]="US"
      • = = toán tử gán, ví dụ biến = value
      • " = trích dẫn giá trị để chụp khoảng trắng ... mặc dù bây giờ tôi nghĩ về nó, sẽ dễ dàng hơn khi để đoạn mã phía trên làm ngược lại mọi thứ để gạch chéo các ký tự khoảng trắng.
    • \\ 1 = chụp nhóm 2 - trong trường hợp này, giá trị của cặp tên / giá trị
    • "= Đóng giá trị trích dẫn để chụp khoảng trắng

bằng tiếng Anh: thay thế từng dòng trong định dạng #name valuebằng toán tử gán mảng theo định dạngA1[name]="value"

Thực hiện

        chmod 755 ~/.colcmp.arrays.tmp.sh

Ở trên sử dụng chmod để làm cho tập tin mảng tập lệnh thực thi.

Tôi không chắc chắn nếu điều này là cần thiết.

Khai báo mảng kết hợp (bash v4 +)

        declare -A A1

Vốn -A chỉ ra rằng các biến được khai báo sẽ là mảng kết hợp .

Đây là lý do tại sao tập lệnh yêu cầu bash v4 trở lên.

Thực thi tập lệnh gán biến mảng của chúng tôi

        source ~/.colcmp.arrays.tmp.sh

Chúng tôi đã sẵn sàng:

  • chuyển đổi tập tin của chúng tôi từ dòng của User valuedòng A1[User]="value",
  • làm cho nó thực thi (có thể), và
  • khai báo A1 là một mảng kết hợp ...

Ở trên chúng tôi nguồn kịch bản để chạy nó trong shell hiện tại. Chúng tôi làm điều này để chúng tôi có thể giữ các giá trị biến được đặt bởi tập lệnh. Nếu bạn thực thi trực tiếp tập lệnh, nó sẽ sinh ra một lớp vỏ mới và các giá trị biến bị mất khi lớp vỏ mới thoát ra, hoặc ít nhất đó là sự hiểu biết của tôi.

Đây phải là một chức năng

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

Chúng tôi làm điều tương tự với $ 1A1 mà chúng tôi làm với $ 2A2 . Nó thực sự nên là một chức năng. Tôi nghĩ tại thời điểm này kịch bản này đủ khó hiểu và nó hoạt động, vì vậy tôi sẽ không sửa nó.

Phát hiện người dùng đã xóa

        for i in "${!A1[@]}"; do
            # check for users removed
        done

Trên vòng lặp thông qua các khóa mảng kết hợp

            if [ "${A2[$i]+x}" = "" ]; then

Ở trên sử dụng thay thế biến để phát hiện sự khác biệt giữa một giá trị không được đặt so với biến đã được đặt rõ ràng thành chuỗi có độ dài bằng không.

Rõ ràng, có rất nhiều cách để xem nếu một biến đã được đặt . Tôi đã chọn một người có nhiều phiếu nhất.

                echo "$i has changed" > Output_File

Ở trên, thêm người dùng $ i vào Output_File

Phát hiện người dùng đã thêm hoặc thay đổi

        USERSWHODIDNOTCHANGE=

Ở trên xóa một biến để chúng tôi có thể theo dõi người dùng không thay đổi.

        for i in "${!A2[@]}"; do
            # detect users added, changed and not changed
        done

Trên vòng lặp thông qua các khóa mảng kết hợp

            if ! [ "${A1[$i]+x}" != "" ]; then

Ở trên sử dụng thay thế biến để xem nếu một biến đã được đặt .

                echo "$i was added as '${A2[$i]}'"

$ i là khóa mảng (tên người dùng) $ A2 [$ i] nên trả về giá trị được liên kết với người dùng hiện tại từ File_2.txt .

Ví dụ: nếu $ iUser1 , thì ở trên đọc là $ {A2 [User1]}

                echo "$i has changed" > Output_File

Ở trên, thêm người dùng $ i vào Output_File

            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then

$ i là khóa mảng (tên người dùng) $ A1 [$ i] nên trả về giá trị được liên kết với người dùng hiện tại từ File_1.txt và $ A2 [$ i] sẽ trả về giá trị từ File_2.txt .

Ở trên so sánh các giá trị liên quan cho người dùng $ i từ cả hai tệp ..

                echo "$i has changed" > Output_File

Ở trên, thêm người dùng $ i vào Output_File

                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"

Ở trên tạo một danh sách người dùng được phân tách bằng dấu phẩy, những người không thay đổi. Lưu ý rằng không có khoảng trắng trong danh sách, nếu không thì kiểm tra tiếp theo sẽ cần được trích dẫn.

        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi

Ở trên báo cáo giá trị của $ USERSWHODIDNOTCHANGE nhưng chỉ khi có một giá trị trong $ USERSWHODIDNOTCHANGE . Cách viết này, $ USERSWHODIDNOTCHANGE không thể chứa bất kỳ khoảng trắng nào. Nếu nó cần khoảng trắng, ở trên có thể được viết lại như sau:

        if [ "$USERSWHODIDNOTCHANGE" != "" ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
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.