두 파일의 내용이 동일한지 확인하는 것이 작동하지 않습니다

두 파일의 내용이 동일한지 확인하는 것이 작동하지 않습니다

따라서 디렉터리의 모든 파일을 살펴보고 이러한 파일에 동일한 디렉터리의 다른 파일과 동일한 내용이 포함되어 있는지 확인하는 스크립트가 있습니다.

Check() 
{
    if [ -e "new.txt" ]
    then
        rm new.txt
    fi
    for item in "$2"/*
    do
        if [ ! -d "$item" ]
        then
            diff "$1" "$item">new.txt
            if [ -s "new.txt" ]
            then
                echo "$1 $item"
                echo "Yes"
            fi
        fi
    done
}

Iterate()
{
    for item in "$2"/*
    do
        if [ ! -d "$item" ]
        then
            Check $item $2
        fi
    done
}

Iterate $1 $2

그리고 카니발

bash script.sh asd /home/ljuben

그러나 스크립트를 실행할 때 파일에 동일한 내용이 포함되어 있지 않으면 항상 "yes"가 표시됩니다.

그리고 아이디어?

답변1

귀하의 스크립트가 첫 번째 인수를 사용하지 않는 것 같습니다. Iterate함수 에 전달된 다음 다시는 나타나지 않습니다.

그러나 실제 질문은 diff두 파일의 모든 조합을 실행하고 차이점의 크기를 확인하는 것입니다. 다른 파일의 경우 차이 크기는 0이 아닙니다. 따라서 스크립트는 Yes각 파일 조합을 보고합니다.다른, 아니 똑같습니다.

A또한 파일을 불필요하게 실행하고 B그 차이점을 두 번 실행하고 있습니다( Avs. 그리고 then vs. Blater ). 파일 목록을 한 번만 생성한 다음 반복하여 이 문제를 해결할 수 있습니다.BA

대체 스크립트:

#!/bin/sh

if [ ! -d "$1" ]; then
    printf 'Usage: %s directory\n' "$0" >&2
    exit 1
fi

# set positional parameters to the list of files in the given directory
set -- "$1"/*

# while there's still files to process...
while [ "$#" -gt 0 ]; do
    # skip over non-regular files
    if [ ! -f "$1" ]; then
        shift
        continue
    fi

    # now process the first item in the list against the other ones
    item=$1

    # shift off the first item from the list
    shift

    # loop over the remaining items...
    for name do
        # we're still not interested in non-regular files
        [ ! -f "$name" ] && continue

        # if they are the same, report this
        if cmp -s "$item" "$name"; then
            printf '%s and %s has same content\n' "$item" "$name"
        fi
    done
done

원하는 경우 두 기능을 모두 사용할 수 있습니다.

#!/bin/sh

if [ ! -d "$1" ]; then
    printf 'Usage: %s directory\n' "$0" >&2
    exit 1
fi

check () {
    # now process the first item in the list against the other ones
    item=$1

    # shift off the first item from the list
    shift

    # loop over the remaining items...
    for name do
        # we're still not interested in non-regular files
        [ ! -f "$name" ] && continue

        # if they are the same, report this
        if cmp -s "$item" "$name"; then
            printf '%s and %s has same content\n' "$item" "$name"
        fi
    done
}

iterate () {
    # set positional parameters to the list of files in the given directory
    set -- "$1"/*

    # while there's still files to process...
    while [ "$#" -gt 0 ]; do
        # only process regular files
        if [ -f "$1" ]; then
            check "$@" # checks the first item against the rest
        fi
        shift # get rid of the first item
    done
}

iterate "$1"

check함수가 자체 파일 목록을 생성 하지 못하게 하는 방법에 주목하세요 . 대신 파일 목록을 전달합니다.

게으른 사람들을 위해:

fdupes -1 /some/directory

답변2

diff다음 옵션과 함께 사용 하려고 합니다 -s.

-s, --동일한 파일 보고

두 파일이 동일한 경우 보고

또한 출력이 포함된 파일을 만들 필요가 없으며 명령이 종료될 때 테스트하면 됩니다 diff.

Check() 
{
    if [ -e "new.txt" ]
    then
        rm new.txt
    fi
    for item in "$2"/*
    do
        if [ ! -d "$item" ]
        then 
            if diff -s "$1" "$item"
            then
                echo "$1 $item"
                echo "Yes"
            fi
        fi
    done
}

Kusalananda가 지적했듯이 cmp이것이 더 나은 옵션이고 휴대성이 더 좋을 수 있습니다. 당신이 사용할 수있는:

if cmp -s "$1" "$item"
then
    echo "$1 $item"
    echo "Yes"
fi

관련 정보