셸 스 크 립 트 는 폴 더 에서 중복 되 는 파일 을 찾 고 삭제 기능 을 제공 합 니 다.
5883 단어 Linux
그러나 셸 스 크 립 트 는 몇 줄 의 명령 을 사용 하여 이와 같은 작업 을 수행 할 수 있 습 니 다. windows 의 셸 스 크 립 트 도구 인 Cygwin 을 통 해 Windows 의 디 렉 터 리 를 스 캔 할 수 있 습 니 다. 원 리 는 다음 과 같 습 니 다.
1. 우선 find 명령 을 통 해 폴 더 의 다음 형식 이 일반 파일 인 모든 파일 을 검색 합 니 다. find 명령 의 출력 은 한 줄 의 파일 입 니 다.
2. find 에서 찾 은 모든 파일 에 대해 MD5 검 사 를 실시 합 니 다. 검사 명령 은 md5sum files 이 고 출력 텍스트 형식 은 MD5SUM 입 니 다. *file
3. 내용 의 파일 의 md5 검사 값 은 같 습 니 다. 모든 MD5SUM 검사 값 을 같은 값 으로 조회 하기 때문에 awk 의 관련 배열 을 사용 하여 다른 파일 을 출력 합 니 다.
4. awk 출력 중 복 된 파일 시트 를 삭제 합 니 다.
셸 스 크 립 트 는 다음 과 같 습 니 다:
#!/bin/bash -
#查找文件夹下相同的文件
#Usage: dupfile.sh [-ds] dirs
# dirs 请用单引号引起来
del=0
silent=0
trap "" PIPE
#参数处理
while test $# -gt 0
do
case $1 in
-d | --delete)
del=1
;;
-s | --silent)
silent=1
;;
-*)
break
;;
*)
break
;;
esac
shift
done
if [ $# -eq 0 ]
then
echo "Usage: dupfile.sh [-ds] dirs" >&2
exit 0
fi
#find查找所有文件并进行MD5校验,
# md5sum对二进制文件输出为 MD5SUM *file
# awk使用关联数组处理相同的md5值并按照格式输出,使用DEL传递参数
# tee命令将管道拷贝一份到进程替换,另一份到stdout
find "$@" -type f -exec md5sum {} + |
awk -v FS="*" -v DEL=$del -v SLT=$silent '
{
if($1 in md5)
md5[$1] = md5[$1] "*" $2
else
md5[$1] = $2
}
END{
for(key in md5)
{
if(DEL==0) K++
n = split(md5[key], files, "*")
if(SLT==1 && n==1) continue
if(DEL==0)
printf("%-*s %s
", length(key), key, files[n])
for(n-- ;n>0 ; n--)
{
K++
if(DEL==0)
printf("%-*s %s
", length(key), "", files[n])
else
printf("\"%s\"
", files[n])
}
}
K = K>0 ? K : 0
print "Total: " K " files"
}' |
tee >(
if [ "$del" -eq 1 ]
then
xargs rm -f
else
tee >/dev/null
fi
)
Cygwin 으로 Windows 에서 테스트 한 결 과 를 보십시오. (열 거 된 모든 디 렉 터 리 에 따옴표 추가 에 주의 하 십시오)
우선, 저 는 E 판 test 디 렉 터 리 에 10 개의 임시 파일 을 만 들 었 습 니 다. 파일 이 모두 비어 있 습 니 다. 테스트 결 과 는 다음 과 같 습 니 다.
hp@hp-PC ~
$ (cd 'E:/test'; i=0; while [ "$i" -lt 10 ] ; do mktemp "./XXXXXX" ; i=$((i+1)) ; done)
./pOsdFm
./5tndDZ
./wjSDR2
./oFrSaG
./7zlZcA
./9sNmEo
./UVDQLR
./qZdDNI
./iwfYdn
./IP52BK
hp@hp-PC ~
$ ./dupfile.sh 'E:/test'
cygwin warning:
MS-DOS style path detected: E:/test
Preferred POSIX equivalent is: /cygdrive/e/test
CYGWIN environment variable option "nodosfilewarning" turns off this warning.
Consult the user's guide for more details about POSIX paths:
http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
d41d8cd98f00b204e9800998ecf8427e E:/test/wjSDR2
E:/test/UVDQLR
E:/test/qZdDNI
E:/test/pOsdFm
E:/test/oFrSaG
E:/test/iwfYdn
E:/test/IP52BK
E:/test/9sNmEo
E:/test/7zlZcA
E:/test/5tndDZ
Total: 10 files
hp@hp-PC ~
$
그 결과 중 복 된 빈 파일 10 개 를 완전히 찾 아 냈 다.
- d 옵션 을 사용 하면 중 복 된 것 을 삭제 하고 그 중 하나 만 유지 할 수 있 습 니 다.
hp@hp-PC ~
$ (cd 'E:/test' ; ls ;)
5tndDZ 7zlZcA 9sNmEo IP52BK iwfYdn oFrSaG pOsdFm qZdDNI UVDQLR wjSDR2
hp@hp-PC ~
$ ./dupfile.sh -d 'E:/test'
"E:/test/UVDQLR"
"E:/test/qZdDNI"
"E:/test/pOsdFm"
"E:/test/oFrSaG"
"E:/test/iwfYdn"
"E:/test/IP52BK"
"E:/test/9sNmEo"
"E:/test/7zlZcA"
"E:/test/5tndDZ"
Total: 9 files
hp@hp-PC ~
$ (cd 'E:/test' ; ls ;)
wjSDR2
다른 상황 을 다시 한 번 테스트 해 보 겠 습 니 다. 저 는 E:/test 디 렉 터 리 에서 10 개의 다른 파일 을 만 들 었 습 니 다. 각 파일 에는 자신의 파일 이름 이 포함 되 어 있 습 니 다.
hp@hp-PC ~
$ (cd 'E:/test'; i=0; while [ "$i" -lt 10 ] ; do name=`mktemp "./XXXXXX"` ; echo "$name" > "$name" ; i=$((i+1)) ; done)
hp@hp-PC ~
$ ./dupfile.sh 'E:/test'
26288eeea00c650ae612dcf5b0efa5ab E:/test/wBMk5c
6f28a86738b227553b116914befd7b55 E:/test/lOT1Yd
1bc7d2563796cf63c7f0d68affb190ef E:/test/haDFBY
679bc5d2d3e17761185ed82d43fd7d4a E:/test/CHOmSd
aaefa81fafd87bf3c3378ef02e22ef5a E:/test/yZ635B
e13b59ae07a9fd0e0a8095701c4003b2 E:/test/QdWtsN
ae2eabc1232111d9f12190b3a62d60bf E:/test/13PWOU
621d060c7c313f06eff1ce21a6b25f0c E:/test/sql7KV
7108830bbf019166d4af9a10030384f3 E:/test/lxGd5y
6dc2d2815a69f8a754503f1301e1cbcb E:/test/efUo7c
Total: 10 files
보 이 는 것 은 모두 다른 파일 입 니 다. 파일 수가 많 을 때 - s 옵션 을 사용 하여 조용히 출력 할 수 있 습 니 다. 중복 되 는 파일 만 표시 하고 중복 되 지 않 는 파일 은 표시 되 지 않 습 니 다.
마지막 으로 흥미 로 운 문제 가 있 습 니 다. 테스트 에서 dupfile 프로그램의 마지막 파이프 끝의 tee > (...) 명령 이 영문 도 모 르 게 종 료 됩 니 다. 스 크 립 트 의 종료 코드 는 141 이 고 SIGPIPE 신호 에 대응 합 니 다.
나의 원래 대본 은 마지막 에 이렇게 썼 다.
tee >(
if [ "$del" -eq 1 ]
then
xargs rm -f
fi
)
분석 결과, > (...) 와 같은 프로 세 스 교체 의 실현 원 리 는 이름 파 이 프 를 통 해 이 루어 집 니 다. 먼저 > (...) 이 위 치 를/dev/fd/63 또는 다른 이름 파이프 파일 로 바 꾼 다음 에 새로운 bash 프로그램 을 시작 하여 > (...) 의 명령 부분 을 실행 하고 bash 프로그램의 표준 입력 은/dev/fd/63 의 파이프 출력 단 으로 대 체 됩 니 다.이때, 왜 SIGPIPE 신 호 를 촉발 합 니까?
괄호 내부 의 명령 부분 은 판단 문 입 니 다. 부정 으로 판 단 될 때 xargs 명령 이 실행 되 지 않 기 때문에 시 작 된 bash 프로그램 이 종 료 됩 니 다. 이때 tee 명령 이/dev/fd/63 이 파이프 에 쓸 때 SIGPIPE 신 호 를 받 습 니 다. 시 작 된 bash 프로그램 이 종료 되 지 않도록 하 는 방법 입 니 다. else 문 구 를 추가 합 니 다. tee >/dev/null.아니면 SIGIPE 신 호 를 무시 하고 trap ""SIGIPE "를 추가 하면 됩 니 다. 동시에 tee 명령 의 stderr 출력 을 tee 2 >/dev/null 무시 합 니 다. > ( ... ).
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
바이너리 파일cat 또는tail, 터미널 디코딩 시 처리 방법cat으로 바이너리 파일을 보려고 할 때 코드가 엉망이 되어 식은땀이 났다. 웹에서 스크롤된 정보의 처리 방법과alias의 설정을 요약합니다. reset 명령을 사용하여 터미널을 재설정합니다.이렇게 하면 고치지 못하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.