디렉터리를 반복적으로 순환하여 특정 확장명의 파일을 삭제하는 방법
으로 반복적으로 반복하고 모든 을 제거해야 합니다..pdf
그리고..doc
디렉터리를 반복적으로 반복적으로 검색할 수는 있지만 위에서 언급한 파일 확장자를 가진 파일을 필터링할 수는 없습니다.
지금까지의 나의 코드
#/bin/sh
SEARCH_FOLDER="/tmp/*"
for f in $SEARCH_FOLDER
do
if [ -d "$f" ]
then
for ff in $f/*
do
echo "Processing $ff"
done
else
echo "Processing file $f"
fi
done
코드를 완성하는 데 도움이 필요합니다. 아무 데도 갈 수가 없어서요.
mouviciel의 답변에 대한 후속 조치로, 당신은 이것을 xargs를 사용하는 대신 for 루프로 할 수도 있습니다.저는 특히 각 반복에서 더 복잡한 작업을 해야 할 경우 자주 xargs가 번거롭다고 생각합니다.
for f in $(find /tmp -name '*.pdf' -or -name '*.doc'); do rm $f; done
많은 사람들이 언급했듯이 파일 이름에 공백이 있으면 이 작업은 실패합니다.IFS(내부 필드 구분자)를 임시로 새 줄 문자로 설정하여 이 문제를 해결할 수 있습니다. 문자 " " " " 가 있을 합니다.\[?*
파일 이름으로.와일드카드 확장(글로브)을 일시적으로 비활성화하여 이 문제를 해결할 수 있습니다.
IFS=$'\n'; set -f
for f in $(find /tmp -name '*.pdf' -or -name '*.doc'); do rm "$f"; done
unset IFS; set +f
파일 이름에 새 줄이 있으면 해당 줄도 작동하지 않습니다.xargs 기반 솔루션을 사용하면 다음과 같은 이점을 얻을 수 있습니다.
find /tmp \( -name '*.pdf' -or -name '*.doc' \) -print0 | xargs -0 rm
는 (으)로 합니다.)-print0
두 가지 모두에 적용됩니다.or
절).
GNU *에는 GNU 및 *BSD find에가 있습니다.-delete
다음과 같은 동작:
find /tmp \( -name '*.pdf' -or -name '*.doc' \) -delete
find
그것을 위해 만들어진 것입니다.
find /tmp -name '*.pdf' -or -name '*.doc' | xargs rm
없이.find
:
for f in /tmp/* tmp/**/* ; do
...
done;
/tmp/*
및 파이dir에 있는 입니다./tmp/**/*
하위 폴더에 있는 파일입니다. 옵션globstar option)을 해야 할 수 .shopt -s globstar
질문에 대한 코드는 다음과 같습니다.
shopt -s globstar
for f in /tmp/*.pdf /tmp/*.doc tmp/**/*.pdf tmp/**/*.doc ; do
rm "$f"
done
에는 bash zsh 없이 zsh)이합니다.shopt -s globstar
는리어울는이 있는 ▁k▁with.set -o globstar
에 shopt -s globstar
또한 bash < 4.3에서 이것은 디렉토리뿐만 아니라 디렉토리에 대한 심볼릭 링크를 통과하며, 이는 일반적으로 바람직하지 않습니다.
재귀적으로 무언가를 수행하려면 재귀를 사용하는 것이 좋습니다(예, 스택 등을 사용하여 수행할 수 있지만, 헤이).
recursiverm() {
for d in *; do
if [ -d "$d" ]; then
(cd -- "$d" && recursiverm)
fi
rm -f *.pdf
rm -f *.doc
done
}
(cd /tmp; recursiverm)
그렇긴 하지만,find
이미 제안한 것처럼 더 나은 선택일 수 있습니다.
셸shell)을.bash
):
#!/bin/bash
# loop & print a folder recusively,
print_folder_recurse() {
for i in "$1"/*;do
if [ -d "$i" ];then
echo "dir: $i"
print_folder_recurse "$i"
elif [ -f "$i" ]; then
echo "file: $i"
fi
done
}
# try get path from param
path=""
if [ -d "$1" ]; then
path=$1;
else
path="/tmp"
fi
echo "base path: $path"
print_folder_recurse $path
이것은 당신의 질문에 직접적으로 대답하지는 않지만, 당신은 한 줄로 당신의 문제를 해결할 수 있습니다.
find /tmp \( -name "*.pdf" -o -name "*.doc" \) -type f -exec rm {} +
find(GNU,에는 일부버찾기(GNU, BSD)가 .-delete
호출하는 대신 사용할 수 있는 작업rm
:
find /tmp \( -name "*.pdf" -o -name "*.doc" \) -type f -delete
bash(버전 4.0 이후)의 경우:
shopt -s globstar nullglob dotglob
echo **/*".ext"
이상입니다.
해당 확장명을 가진 파일(또는 dirs)을 선택하기 위한 뒤에 오는 확장명 ".ext".
globstar 옵션은 **(재귀적으로 검색)를 활성화합니다.
옵션 nullglob은 파일/dir가 일치하지 않는 *를 제거합니다.
옵션 dotglob에는 점으로 시작하는 파일(숨겨진 파일)이 포함됩니다.
bash 4.3 이전에 주의하십시오.**/
또한 바람직하지 않은 디렉토리에 대한 심볼릭 링크를 통과합니다.
이 방법은 공백을 잘 처리합니다.
files="$(find -L "$dir" -type f)"
echo "Count: $(echo -n "$files" | wc -l)"
echo "$files" | while read file; do
echo "$file"
done
하나씩 편집, 수정
function count() {
files="$(find -L "$1" -type f)";
if [[ "$files" == "" ]]; then
echo "No files";
return 0;
fi
file_count=$(echo "$files" | wc -l)
echo "Count: $file_count"
echo "$files" | while read file; do
echo "$file"
done
}
이것이 제가 아는 가장 간단한 방법입니다.rm **/@(*.doc|*.pdf)
**
이 작업을 반복적으로 수행합니다.
@(*.doc|*.pdf)
PDF 또는 문서로 끝나는 파일을 찾습니다.
교체하여 안전하게 테스트하기 쉽습니다.rm
와 함께ls
다음 함수는 의 모든 디렉터리를 통해 재귀적으로 반복됩니다.\home\ubuntu
디렉토리(Ubuntu 아래의 전체 디렉토리 구조) 및 필요한 체크 인을 적용합니다.else
블록으로 막다
function check {
for file in $1/*
do
if [ -d "$file" ]
then
check $file
else
##check for the file
if [ $(head -c 4 "$file") = "%PDF" ]; then
rm -r $file
fi
fi
done
}
domain=/home/ubuntu
check $domain
의 출력을 파이프로 연결할 이유가 없습니다.find
다른 유틸리티로. find
을 가지고 있습니다.-delete
내장된 깃발.
find /tmp -name '*.pdf' -or -name '*.doc' -delete
제공된 다른 답변에는 a로 시작하는 파일이나 디렉토리가 포함되지 않습니다. 다음은 저에게 도움이 되었습니다.
#/bin/sh
getAll()
{
local fl1="$1"/*;
local fl2="$1"/.[!.]*;
local fl3="$1"/..?*;
for inpath in "$1"/* "$1"/.[!.]* "$1"/..?*; do
if [ "$inpath" != "$fl1" -a "$inpath" != "$fl2" -a "$inpath" != "$fl3" ]; then
stat --printf="%F\0%n\0\n" -- "$inpath";
if [ -d "$inpath" ]; then
getAll "$inpath"
#elif [ -f $inpath ]; then
fi;
fi;
done;
}
가장 간단한 해결책은 재귀를 사용하는 것이라고 생각합니다. 다음 예제에서는 디렉터리와 하위 디렉터리의 모든 파일 이름을 인쇄했습니다.
필요에 따라 수정할 수 있습니다.
#!/bin/bash
printAll() {
for i in "$1"/*;do # for all in the root
if [ -f "$i" ]; then # if a file exists
echo "$i" # print the file name
elif [ -d "$i" ];then # if a directroy exists
printAll "$i" # call printAll inside it (recursion)
fi
done
}
printAll $1 # e.g.: ./printAll.sh .
출력:
> ./printAll.sh .
./demoDir/4
./demoDir/mo st/1
./demoDir/m2/1557/5
./demoDir/Me/nna/7
./TEST
그것은 공간에서도 잘 작동합니다!
참고: 사용할 수 있습니다.echo $(basename "$i") # print the file name
경로 없이 파일 이름을 인쇄합니다.
OR: 사용echo ${i%/##*/}; # print the file name
외부에 전화하지 않고도 매우 빠르게 실행됩니다.basename
.
그냥 해요
find . -name '*.pdf'|xargs rm
명령을 실행하는 데 사용되는 셸을 변경할 수 있는 경우 ZSH를 사용하여 작업을 수행할 수 있습니다.
#!/usr/bin/zsh
for file in /tmp/**/*
do
echo $file
done
모든 파일/폴더를 반복적으로 순환합니다.
다음은 지정된 디렉터리를 반복적으로 순환하고 모든 내용을 나열합니다.
for d in /home/ubuntu/*;
do
echo "listing contents of dir: $d";
ls -l $d/;
done
언급URL : https://stackoverflow.com/questions/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi
'programing' 카테고리의 다른 글
Interlocked의 과부하가 없는 이유는 무엇입니까?Double을 매개 변수로 허용하는 추가? (0) | 2023.05.08 |
---|---|
날짜 시간 대 날짜 시간 오프셋 (0) | 2023.05.08 |
PostgreSQL에서 가로 조인과 하위 쿼리의 차이점은 무엇입니까? (0) | 2023.05.08 |
Postgre용 GUI 도구SQL (0) | 2023.05.08 |
문자열 구분 기호로 문자열을 분할하려면 어떻게 해야 합니까? (0) | 2023.05.08 |