다음과 같은 명령:
find /directory -type f -name "*.txt" -print | xargs rm
디렉터리와 하위 디렉터리의 모든 파일을 삭제 .txt
하면 됩니다. 그러나 find
예를 들어 파일 확장자에 대한 변수나 배열을 만든 다음 을 배치하면
TXT=(*.txt)
for ii in ${TXT[@]}; do
find /directory -type f -name $TXT -print | xargs rm
done
이 명령은 하위 디렉터리의 파일을 삭제하지 않습니다 .txt
. 왜? 하위 디렉터리의 파일을 삭제하기 위해 두 번째 코드 부분을 어떻게 변경합니까?
PS: 파일 확장자가 여러 개 있어서 배열을 사용했습니다.
답변1
배열 할당,
TXT=(*.txt)
*.txt
패턴과 일치하는 현재 디렉터리의 파일 이름 목록으로 패턴을 확장합니다 . 쉘은 할당 시 이를 수행합니다. 당신이 원하는 것이 아닌가요? 다음과 같은 find
리터럴 문자열을 제공하려고 합니다 *.txt
.
pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +
여기서도 이를 제거 xargs rm
하고 rm
바로 실행을 시작합니다 find
. 대부분의 현재 구현은 비표준으로 대체 find
될 수 있습니다 .-delete
-exec rm {} +
pattern='*.txt'
find /directory -type f -name "$pattern" -delete
여기서는 단일 패턴만 다루기 때문에 루프가 필요하지 않습니다. 또한 "$pattern"
호출 시 따옴표가 find
중요합니다. 그렇지 않으면 패턴이 시작하기 전에 현재 디렉터리에서 일치하는 모든 파일 이름으로 대체됩니다 find
.
여러 모드의 경우 다음과 같은 루프를 수행할 수 있습니다.
patterns=( '*.txt' '*.tmp' )
for pattern in "${patterns[@]}"; do
find /directory -type f -name "$pattern" -delete
done
배열 할당의 따옴표는 쉘이 패턴을 파일 이름 일치 패턴으로 사용하는 것을 방지하기 때문에 중요합니다. 같은 이유로 인용하는 "${patterns[@]}"
것도 똑같이 중요합니다."$pattern"
find
또 다른 접근 방식은 여러 스키마가 있더라도 을 한 번만 호출하는 것입니다 . /directory
디렉터리 계층 구조가 큰 경우 작업 속도가 크게 향상될 수 있습니다. 다음 코드는 일련의 -name
테스트를 구축하여 find
이를 수행합니다 .
patterns=( '*.txt' '*.tmp' )
name_tests=( )
for pattern in "${patterns[@]}"; do
name_tests+=( -o -name "$pattern" )
done
# "${name_tests[@]:1}" removes the initial "-o", which shouldn't be there.
name_tests=( '(' "${name_tests[@]:1}" ')' )
find /directory -type f "${name_tests[@]}" -delete
위 스크립트에서 마지막에 실행되는 실제 명령은 다음과 같습니다.
find /directory -type f '(' -name '*.txt' -o -name '*.tmp' ')' -delete
...이렇게 하면 파일 이름 접미사가 붙은 모든 일반 파일이 삭제됩니다..txt
또는 .tmp
디렉토리 안이나 아래의 어느 곳에서나 가능합니다 /directory
.