쓸모없는 파일(예: ,,,,)이 포함된 여러 디렉터리가 있습니다 *.tmp
.desktop.ini
Thumbs.db
.picasa.ini
모든 드라이브를 검색하여 일부 파일만 포함된 디렉터리를 찾으려면 어떻게 해야 합니까?
답변1
, 및/또는 이외의 이름이 없는 *.tmp
모든 desktop.ini
디렉토리 Thumbs.db
를 찾으려면 다음을 수행하십시오 .picasa.ini
.
find . -type d -exec bash -O dotglob -c '
for dirpath do
ok=true
seen_files=false
set -- "$dirpath"/*
for name do
[ -d "$name" ] && continue # skip dirs
seen_files=true
case "${name##*/}" in
*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
*) ok=false; break
esac
done
"$seen_files" && "$ok" && printf "%s\n" "$dirpath"
done' bash {} +
find
이는 현재 디렉토리 아래(포함)의 디렉토리를 찾아 쉘 스크립트에 전달하는 데 사용됩니다 .
쉘 스크립트는 주어진 디렉토리 경로를 반복하고 각 디렉토리 경로에 대해 *
그 안에서 확장됩니다( 숨겨진 이름을 캡처하도록 dotglob
쉘 옵션을 설정하십시오 ).bash
그런 다음 결과 이름 목록을 반복하여 우리가 찾으려는 특정 패턴 및 이름과 일치시킵니다(디렉터리 무시). 혹시 찾으신다면다른이름이 목록과 일치하지 않으면 (from has was ) ok
로 설정되고 내부 루프에서 벗어납니다.false
true
다음 유형을 제외한 모든 유형의 파일을 보면 이 seen_files
변수는 다음과 같습니다.true
목차(또는디렉토리에 대한 심볼릭 링크). 이 변수는 다른 하위 디렉터리만 포함하는 하위 디렉터리를 보고하는 것을 방지하는 데 도움이 됩니다.
$seen_files
그런 다음 and $ok
( true
또는 ) 을 실행 false
하고 둘 다인 경우 true
해당 디렉터리에 최소한 하나의 일반 파일이 포함되어 있음을 의미하며,목록에 있는 파일 이름만 포함, 디렉토리의 경로 이름을 인쇄합니다.
바꾸다
set -- "$dirpath"/*
for name do
당신은 분명히 이것을 할 수 있습니다
for name in "$dirpath"/*; do
대신에.
시험:
$ tree
.
`-- dir
|-- Thumbs.db
`-- dir
|-- file.tmp
`-- something
2 directories, 3 files
( find
여기서 명령이 실행되어 출력이 생성됩니다...)
./dir
즉, 디렉터리 ./dir
에는 목록의 이름(디렉터리 무시)만 포함되고 ./dir/dir
다른 콘텐츠도 포함됩니다.
[ -d "$name" ] && continue
코드에서 제거하면 목록( )에 없는 이름이 ./dir
포함되어 있으므로 디렉터리를 찾을 수 없습니다 .dir
답변2
find, xargs, ls, sed, wc 및 awk 명령의 조합을 사용하면 작동합니다.
find . -type f \( -iname "desktop.ini" -o -name "thumb.db" \) -printf %h\\0 | xargs -0 -I "{}" sh -c 'printf "{}\t"; ls -l "{}" | sed -n "1!p" | wc -l' | awk '$2 == "1" {print $0}'
설명하다:
find .
현재 디렉토리에서 찾기-type f
파일만 찾기\( -iname "desktop.ini" -o -name "thumb.db" \)
여기서 파일 이름은 "desktop.ini" 또는 "thumb.db"이며 대소문자를 구분하지 않습니다.printf %h\\0
파일 이름 + ASCII NUL의 선두 디렉토리를 인쇄합니다.xargs -0 -I "{}" sh -c 'printf "{}\t"; ls -l "{}"
출력 디렉터리를 인쇄하고ls -l
각 디렉터리에서 실행sed -n "1!p" | wc -l'
전체 파일과 디렉터리가 포함된 첫 번째 줄을 제외하고ls -l
줄 수를 계산합니다.awk '$2 == "1" {print $0}'
개수가 "1"과 같으면 해당 줄을 인쇄합니다.
답변3
파일이나 폴더를 이름으로 지정하는 것이 좋습니다. 예를 들면 다음과 같습니다.
find ${HOME} -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm
( ) "thumbs.db" -type f
라는 이름의 모든 파일을 찾아서 ( ) 삭제합니다 ( ) .-iname
i
iname
rm
다음과 같은 파일 이름 패턴을 사용할 수 있습니다.
find ${HOME} -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm
경고하다:입력하신 내용에 주의하시기 바랍니다. 요청 없이 삭제될 수 있습니다.
정기적으로 백업하십시오. 정리 프로세스를 시작하기 전에 좋은 시간이 될 수 있습니다!
무엇을 기대해야 할지 알고 싶다면 rm
작업을 수행하기 전에 파일 목록을 살펴보십시오. 예를 들면 다음과 같습니다.
find ${HOME} -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l
답변4
GNU find
및 GNU를 사용하면 모든 파일을 보고하고 일치시킬 awk
수 있습니다 .find
awk
find . -depth -type d -printf '%p/\0' -o -printf '%p\0' |
gawk -F/ -v OFS=/ -v RS='\0' -v IGNORECASE=1 '
/\/$/ {
NF--
if (good[$0] == 0 && bad[$0] > 0) print
next
}
{
name = $NF
NF--
if (name ~ /^(.*\.tmp|desktop\.ini|Thumbs\.db|\.picasa\.ini)$/)
bad[$0]++
else
good[$0]++
}'
빈 디렉터리도 포함하려면 제거하세요 && bad[$0] > 0
. 대소문자를 구분하려면 제거하세요 -v IGNORECASE=1
.