我需要递归遍历一个目录并删除扩展名为.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
Run Code Online (Sandbox Code Playgroud)
我需要帮助才能完成代码,因为我无处可去.
Jam*_*ven 192
作为mouviciel答案的后续内容,您也可以将其作为for循环,而不是使用xargs.我经常发现xargs很麻烦,特别是如果我需要在每次迭代中做一些更复杂的事情.
for f in $(find /tmp -name '*.pdf' -or -name '*.doc'); do rm $f; done
Run Code Online (Sandbox Code Playgroud)
正如许多人所评论的那样,如果文件名中有空格,则会失败.您可以通过临时将IFS(内部字段分隔符)设置为换行符来解决此问题.如果\[?*文件名中有通配符,则也会失败.您可以通过暂时禁用通配符扩展(globbing)来解决此问题.
IFS=$'\n'; set -f
for f in $(find /tmp -name '*.pdf' -or -name '*.doc'); do rm "$f"; done
unset IFS; set +f
Run Code Online (Sandbox Code Playgroud)
如果您的文件名中有换行符,那么这也不起作用.你最好使用基于xargs的解决方案:
find /tmp \( -name '*.pdf' -or -name '*.doc' \) -print0 | xargs -0 rm
Run Code Online (Sandbox Code Playgroud)
(此处必须使用转义括号才能-print0适用于这两个or条款.)
GNU和*BSD find也有一个-delete动作,如下所示:
find /tmp \( -name '*.pdf' -or -name '*.doc' \) -delete
Run Code Online (Sandbox Code Playgroud)
mou*_*iel 133
find 就是这样做的.
find /tmp -name '*.pdf' -or -name '*.doc' | xargs rm
Run Code Online (Sandbox Code Playgroud)
小智 58
没有find:
for f in /tmp/* tmp/**/* ; do
...
done;
Run Code Online (Sandbox Code Playgroud)
/tmp/*是dir /tmp/**/*中的文件,是子文件夹中的文件.您可能需要启用globstar选项(shopt -s globstar).所以对于这个问题,代码应如下所示:
shopt -s globstar
for f in /tmp/*.pdf /tmp/*.doc tmp/**/*.pdf tmp/**/*.doc ; do
rm "$f"
done
Run Code Online (Sandbox Code Playgroud)
请注意,这需要bash≥4.0(或zsh没有shopt -s globstar,或ksh set -o globstar而不是shopt -s globstar).此外,在bash <4.3中,它遍历到目录和目录的符号链接,这通常是不可取的.
fal*_*tro 26
如果你想以递归方式做某事,我建议你使用递归(是的,你可以使用堆栈等来做,但是嘿).
recursiverm() {
for d in *; do
if [ -d "$d" ]; then
(cd -- "$d" && recursiverm)
fi
rm -f *.pdf
rm -f *.doc
done
}
(cd /tmp; recursiverm)
Run Code Online (Sandbox Code Playgroud)
也就是说,find可能是一个更好的选择,正如已经提出的那样.
Eri*_*ang 15
以下是使用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
Run Code Online (Sandbox Code Playgroud)
Oli*_*rth 13
这不会直接回答您的问题,但您可以通过单行解决您的问题:
find /tmp \( -name "*.pdf" -o -name "*.doc" \) -type f -exec rm {} +
Run Code Online (Sandbox Code Playgroud)
某些版本的find(GNU,BSD)有一个-delete你可以使用而不是调用的动作rm:
find /tmp \( -name "*.pdf" -o -name "*.doc" \) -type f -delete
Run Code Online (Sandbox Code Playgroud)
这种方法很好地处理空间.
files="$(find -L "$dir" -type f)"
echo "Count: $(echo -n "$files" | wc -l)"
echo "$files" | while read file; do
echo "$file"
done
Run Code Online (Sandbox Code Playgroud)
编辑,逐个修复
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
}
Run Code Online (Sandbox Code Playgroud)
小智 7
对于 bash(从 4.0 版开始):
shopt -s globstar nullglob dotglob
echo **/*".ext"
Run Code Online (Sandbox Code Playgroud)
就这样。
尾随扩展名“.ext”用于选择具有该扩展名的文件(或目录)。
选项 globstar 激活 **(递归搜索)。
选项 nullglob 在不匹配任何文件/目录时删除 *。
选项 dotglob 包括以点开头的文件(隐藏文件)。
请注意,在 bash 4.3 之前,**/还会遍历到不需要的目录的符号链接。