두 파일에 동일한 데이터가 포함되어 있는지 여부를 확인 해야하는 쉘 스크립트가 있습니다. 많은 파일에 대해이 작업을 수행하며 스크립트에서 diff
명령이 성능 병목 현상으로 보입니다.
라인은 다음과 같습니다.
diff -q $dst $new > /dev/null
if ($status) then ...
파일을 비교하는 더 빠른 방법이있을 수 diff
있습니까 , 기본값 대신 사용자 정의 알고리즘 일까요?
두 파일에 동일한 데이터가 포함되어 있는지 여부를 확인 해야하는 쉘 스크립트가 있습니다. 많은 파일에 대해이 작업을 수행하며 스크립트에서 diff
명령이 성능 병목 현상으로 보입니다.
라인은 다음과 같습니다.
diff -q $dst $new > /dev/null
if ($status) then ...
파일을 비교하는 더 빠른 방법이있을 수 diff
있습니까 , 기본값 대신 사용자 정의 알고리즘 일까요?
답변:
cmp
첫 번째 바이트 차이에서 멈출 것이라고 믿습니다 .
cmp --silent $old $new || echo "files are different"
cmp -s $old $new
작동합니다. -s
의 약어--silent
cmp
파일 크기를 먼저 확인합니다. 여기에 추가 최적화를보고 싶다면 GNU 버전이 있습니다 : git.savannah.gnu.org/cgit/diffutils.git/tree/src/cmp.c
@Alex Howansky는 이것을 위해 'cmp --silent'를 사용했습니다. 그러나 긍정적 인 반응과 부정적인 반응이 모두 필요하므로 다음을 사용하십시오.
cmp --silent file1 file2 && echo '### SUCCESS: Files Are Identical! ###' || echo '### WARNING: Files Are Different! ###'
그런 다음 터미널에서 또는 ssh를 사용하여 상수 파일과 비교하여 파일을 확인할 수 있습니다.
왜 두 파일 내용의 해시를 얻지 못합니까?
이 스크립트를 사용해보고 (예 : script.sh) 다음과 같이 실행하십시오. script.sh file1.txt file2.txt
#!/bin/bash
file1=`md5 $1`
file2=`md5 $2`
if [ "$file1" = "$file2" ]
then
echo "Files have the same content"
else
echo "Files have NOT the same content"
fi
1/(2^511)
입니다. 의도적으로 충돌을 시도하는 누군가에 대해 걱정하지 않는 한이 방법이 오 탐지 를 만드는 아이디어는 실제로 심각한 문제가 아닙니다. cmp
파일이 일치하지 않는 경우 전체 파일을 읽을 필요가 없기 때문에 여전히 더 효율적입니다.
내가 평판을 얻지 못해 평판이 충분하지 않기 때문에이 음식을 의견으로 추가 할 수 없습니다.
그러나 cmp
명령 을 사용 하려는 경우 (자세한 설명이 필요하지 않은 경우) 종료 상태를 파악하면됩니다. cmp
매뉴얼 페이지 당 :
파일이 '-'이거나 누락 된 경우 표준 입력을 읽으십시오. 입력이 동일하면 종료 상태는 0이고, 다를 경우 1, 문제가 있으면 2입니다.
따라서 다음과 같은 작업을 수행 할 수 있습니다.
STATUS="$(cmp --silent $FILE1 $FILE2; echo $?)" # "$?" gives exit status for each comparison
if [[$STATUS -ne 0]]; then # if status isn't equal to 0, then execute code
DO A COMMAND ON $FILE1
else
DO SOMETHING ELSE
fi
cmp --silent $FILE1 $FILE2 ; if [ "$?" == "1" ]; then echo "files differ"; fi
좀 더 복잡한 방법입니다 cmp --silent $FILE1 $FILE2 || echo "files differ"
. 대신 사용합니다 $?
. 결과적으로 명령의 존재 상태가 비교됩니다. 그리고 그것은 다른 대답이하는 것입니다. btw. 누군가 어려움을 겪고 있다면 --silent
(busybox) 모든 곳에서 지원되지 않습니다. 사용-s
다르지 않은 파일의 경우, 읽기가 과거에 있었던 경우에도 모든 방법을 사용하여 두 파일을 모두 읽어야합니다.
대안이 없습니다. 따라서 특정 시점에 해시 또는 체크섬을 만들려면 전체 파일을 읽어야합니다. 큰 파일은 시간이 걸립니다.
파일 메타 데이터 검색은 큰 파일을 읽는 것보다 훨씬 빠릅니다.
파일이 다르다는 것을 확인하는 데 사용할 수있는 파일 메타 데이터가 있습니까? 파일 크기? 또는 파일의 작은 부분을 읽는 파일 명령의 결과?
파일 크기 예제 코드 조각 :
ls -l $1 $2 |
awk 'NR==1{a=$5} NR==2{b=$5}
END{val=(a==b)?0 :1; exit( val) }'
[ $? -eq 0 ] && echo 'same' || echo 'different'
파일 크기가 같으면 전체 파일 읽기가 고착 된 것입니다.
ls -n
사용자 또는 그룹 이름에 공백이있는 경우 문제를 피하기 위해 사용하십시오 .
cksum 명령도 사용하십시오 :
chk1=`cksum <file1> | awk -F" " '{print $1}'`
chk2=`cksum <file2> | awk -F" " '{print $1}'`
if [ $chk1 -eq $chk2 ]
then
echo "File is identical"
else
echo "File is not identical"
fi
cksum 명령은 파일의 바이트 수를 출력합니다. 'man cksum'을 참조하십시오.
md5
어쨌든 전체 파일 을 읽으므로 cmp
첫 번째 차이에서 멈추는 것이 훨씬 빠릅니다.
Raspberry Pi 3B + (일부 오버레이 파일 시스템을 사용하고 있으며 주기적으로 동기화해야 함)를 사용하여 일부 테스트를 수행하면서 diff -q 및 cmp -s에 대한 자체 비교를 실행했습니다. 이것은 / dev / shm 내부의 로그이므로 디스크 액세스 속도는 문제가되지 않습니다.
[root@mypi shm]# dd if=/dev/urandom of=test.file bs=1M count=100 ; time diff -q test.file test.copy && echo diff true || echo diff false ; time cmp -s test.file test.copy && echo cmp true || echo cmp false ; cp -a test.file test.copy ; time diff -q test.file test.copy && echo diff true || echo diff false; time cmp -s test.file test.copy && echo cmp true || echo cmp false
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 6.2564 s, 16.8 MB/s
Files test.file and test.copy differ
real 0m0.008s
user 0m0.008s
sys 0m0.000s
diff false
real 0m0.009s
user 0m0.007s
sys 0m0.001s
cmp false
cp: overwrite âtest.copyâ? y
real 0m0.966s
user 0m0.447s
sys 0m0.518s
diff true
real 0m0.785s
user 0m0.211s
sys 0m0.573s
cmp true
[root@mypi shm]# pico /root/rwbscripts/utils/squish.sh
나는 그것을 두 번 실행했다. cmp -s는 내가 사용하고있는 테스트 상자에서 일관되게 약간 짧은 시간을 보냈습니다. 따라서 cmp -s를 사용하여 두 파일 사이에서 작업을 수행하려는 경우 ....
identical (){
echo "$1" and "$2" are the same.
echo This is a function, you can put whatever you want in here.
}
different () {
echo "$1" and "$2" are different.
echo This is a function, you can put whatever you want in here, too.
}
cmp -s "$FILEA" "$FILEB" && identical "$FILEA" "$FILEB" || different "$FILEA" "$FILEB"