나는 많은 수의 파일을 포함하는 일부 디렉토리를 가지고 있습니다. 특정 문자열은 포함하고 다른 문자열은 포함하지 않는 파일을 삭제하여 이러한 디렉터리를 정리하고 싶습니다.
예를 들어 파일 이름에 "AAA"가 포함되어 있지만 "BBB", "CCC" 또는 "DDD"는 포함되어 있지 않은 파일을 삭제합니다.
가능합니까?
답변1
find
삭제할 파일을 재귀적으로 검색하려는 일부 최상위 디렉터리에서 다음을 사용합니다.
find . -type f -name '*AAA*' ! -name '*BBB*' ! -name '*CCC*' ! -name '*DDD*' -print
위의 명령은 현재 디렉토리 안이나 아래의 모든 일반 파일을 찾습니다. 그 중에서 이름에 가 포함된 파일을 선택하고 이름에 , 또는 AAA
가 포함된 파일을 선택 취소한 다음 (각각 바로 뒤에 오는 테스트를 부정함) 여전히 선택된 파일의 경로 이름을 인쇄합니다.BBB
CCC
DDD
!
여기에 사용된 패턴은 일반적인 파일 이름 일치 패턴입니다(정규 표현식 아님). 현재 디렉터리에서 이름이 실수로 일치하는 것을 방지하려면 따옴표로 묶어야 합니다.
파일을 삭제하려면 -print
로 변경하세요 -delete
.
-delete
비표준 술어(일반적으로 구현되는 술어임에도 불구하고) 이므로 -exec rm {} +
사용하는 것이 더 이식성이 좋습니다. 이렇게 하면 rm
선택한 파일을 최대한 한 번에 실행합니다.
bash
일반적으로 셸을 가정하고 파일 이름이 포함 패턴과 일치하고 제외 패턴과 일치하지 않아야 한다고 가정할 때 포함 및 제외할 패턴 목록이 두 개 있습니다 .
include=( '*AAA*' '*123*' )
exclude=( '*BBB*' '*CCC*' '*DDD*' )
or_filter=()
and_filter=()
for pattern in "${include[@]}"; do
or_filter+=( -o -name "$pattern" )
done
or_filter=( "${or_filter[@]:1}" ) # remove initial -o
for pattern in "${exclude[@]}"; do
and_filter+=( ! -name "$pattern" )
done
find . -type f \( "${or_filter[@]}" \) "${and_filter[@]}" -print