디렉토리를 반복적으로 반복하여 특정 확장자를 가진 파일을 삭제하는 방법
디렉토리를 재귀 적으로 반복하고 확장자가 .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
아무데도 못 가니까 코드를 완성하는 데 도움이 필요합니다.
find
그것을 위해 만들어졌습니다.
find /tmp -name '*.pdf' -or -name '*.doc' | xargs rm
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와 * BSD find에도 -delete
다음과 같은 동작이 있습니다.
find /tmp \( -name '*.pdf' -or -name '*.doc' \) -delete
없이 find
:
for f in /tmp/* tmp/**/* ; do
...
done;
/tmp/*
디렉토리에 /tmp/**/*
있는 파일이며 하위 폴더에있는 파일입니다. globstar 옵션 ( shopt -s globstar
) 을 활성화해야 할 수도 있습니다 . 따라서 질문의 경우 코드는 다음과 같아야합니다.
shopt -s globstar
for f in /tmp/*.pdf /tmp/*.doc tmp/**/*.pdf tmp/**/*.doc ; do
rm "$f"
done
이를 위해서는 bash ≥4.0이 필요합니다 (또는 zsh없이 shopt -s globstar
또는 set -o globstar
대신 ksh 사용 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
이미 제안 된 것처럼 더 나은 선택 일 것입니다.
다음은 쉘 ( 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 {} +
Some versions of find (GNU, BSD) have a -delete
action which you can use instead of calling rm
:
find /tmp \( -name "*.pdf" -o -name "*.doc" \) -type f -delete
This method handles spaces well.
files="$(find -L "$dir" -type f)"
echo "Count: $(echo -n "$files" | wc -l)"
echo "$files" | while read file; do
echo "$file"
done
Edit, fixes off-by-one
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
}
For bash (since version 4.0):
shopt -s globstar nullglob dotglob
echo **/*".ext"
That's all.
The trailing extension ".ext" there to select files (or dirs) with that extension.
Option globstar activates the ** (search recursivelly).
Option nullglob removes an * when it matches no file/dir.
Option dotglob includes files that start wit a dot (hidden files).
Beware that before bash 4.3, **/
also traverses symbolic links to directories which is not desirable.
The following function would recursively iterate through all the directories in the \home\ubuntu
directory( whole directory structure under ubuntu ) and apply the necessary checks in else
block.
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
There is no reason to pipe the output of find
into another utility. find
has a -delete
flag built into it.
find /tmp -name '*.pdf' -or -name '*.doc' -delete
The for answers provided will not include files or directories that start with a . the following worked for me:
#/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;
}
Just do
find . -name '*.pdf'|xargs rm
The following will loop through the given directory recursively and list all the contents :
for d in /home/ubuntu/*; do echo "listing contents of dir: $d"; ls -l $d/; done
'IT story' 카테고리의 다른 글
UITableView 헤더 섹션 사용자 정의 (0) | 2020.06.21 |
---|---|
이미지를 Base64 문자열로 변환하는 방법은 무엇입니까? (0) | 2020.06.21 |
jQuery에서 입력 [유형 = 텍스트]의 값 변경 감지 (0) | 2020.06.21 |
위도에 가려면 Google Maps URL에서 어떤 매개 변수를 사용해야합니까? (0) | 2020.06.21 |
jQuery를 사용한 파일 업로드 진행률 표시 줄 (0) | 2020.06.21 |