![删除包含某个文件的目录(以“!”开头的目录除外)](https://linux22.com/image/164357/%E5%88%A0%E9%99%A4%E5%8C%85%E5%90%AB%E6%9F%90%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E7%9B%AE%E5%BD%95%EF%BC%88%E4%BB%A5%E2%80%9C%EF%BC%81%E2%80%9D%E5%BC%80%E5%A4%B4%E7%9A%84%E7%9B%AE%E5%BD%95%E9%99%A4%E5%A4%96%EF%BC%89.png)
我正在尝试按照标题所述进行操作。我有一台服务器,每天轮换电影列表,而我的存储空间不足。我有一个脚本可以遍历并删除最旧的 .mp4。我留下了与该电影相关的剩余文件,只是占用了空间。我想删除整个文件夹。
目前这是我的代码:
#Finds oldest *.mp4 and deletes it.
stat --printf='%Y %n\0' "$dir"/New_Movies/*/*.mp4 | sort -z | sed -zn '1s/[^ ]\{1,\} //p' | xargs -0 rm
以下是我尝试查找不包含 *.mp4 也不包含“!”的目录的失败尝试。在目录名称中。示例名称:“!Action”。
for d in "$dir"/New_Movies/*/; do
if ! [ -e "*!*" ]; then
[ -f "$d"*.mp4 ] || printf '%s\n' "$d"
fi
done
在测试时,我得到 3 个不同的输出,每次运行时一个。
运行 1:它给了我正确的目录以及所有包含“!”的目录。 (它们是快捷方式,所以我认为它们看起来是空的)。
运行 2:与上面相同,但每个 printf 之间有很多“-bash: [: 太多参数”。
运行3:破坏代码并且不运行。
之后:按顺序重复运行 1-3。
目录示例:
/新电影/
/New_Movies/*/index.php
/New_Movies/foo/foo.mp4、foo.jpg、foo.xml
/New_Movies/bar/bar.jpg, bar.xml
运行脚本后,我应该只剩下 /New_Movies/foo 及其内容。
答案1
在默认情况下禁用历史扩展的脚本内!
,您应该能够!
使用简单的 shell glob 来匹配名称不包含的目录:或者*[^!]*
(*[!!]*
其中第一个!
是 POSIX 否定)。
有多种方法可以测试“不包含 *.mp4 的目录”情况;我想到的是使用另一个带有 shellset
内置函数的 glob,并测试结果的位置参数数量$#
。
把它放在一起:
#!/bin/bash
shopt -s nullglob
for d in ./*[^!]*/; do
set -- "$d"/*.mp4
if [ $# -eq 0 ]; then
printf '%s\n' "$d"
fi
done
!
如果您禁用历史扩展或转义glob 中的字符,则此方法应该在交互式 shell 中工作*[^\!]*
注:您的标题指的是以“!”开头的目录但在你提到的文字中包含“!”的目录。我假设是后一种情况,但如果您只想排除前者,则从*
全局中删除前导。
答案2
首先,我认为您的方法非常危险,因为您正在搜索并对未找到的结果进行删除操作。如果您将此检查附加到检查和删除最旧mp4
文件的脚本中,将会更加安全和有益。
尽管如此,这里有一个脚本可以满足您的需要。我包含了大量用于日志记录和调试目的的行,以便您可以查看正在检查的内容、时间以及每个文件夹的分类方式。稍后删除以减少冗余。
#!/bin/bash
# TO USE NAME IT script_check_dirs.sh and place it in the top directory
# RUN SOMETHING ALONG THE LINES OF:
#find . -mindepth 1 -type d -exec ./script_check_dirs.sh {} \;
bn=$(basename $1); #FOLDER NAME VARIABLE
echo $bn >> dir_list; #LOG FILE LISTING ALL FOLDERS
if [[ $bn == *\!* ]] ; #FIRST CHECK FOR SYMBOL IN FOLDER NAME
then
echo -e "\n DIRECTORY:$bn -" DONT CHECK directory "$bn" ;
echo $bn >> dir_list_good ; #APPEND TO LOG FILE LISTING FOLDERS TO KEEP
else
echo -e "\n DIRECTORY:$bn -- CHECKING DIRECTORY $bn because it does not have ! in its name ";
f_v=$(find $bn -type f | grep -i "mp4" );
if [[ $? -eq 0 ]] ;
then
echo -e "\t" FOUND MP4 FILES in $bn;
echo -e "\t\t" $f_v ;
echo -e "\t" NO - DONT DELETE $bn ;
echo $bn >> dir_list_good; #APPEND TO LOG FILE LISTING FOLDERS TO KEEP
else
echo -e "\t YES -- DIRECTORY $bn CAN BE DELETED because there were no mp4 files found and directory name $bn has no ! " ;
echo $bn >> dir_list_del; #APPEND TO LOG FILE LISTING FOLDERS TO DELETE
fi ;
fi
然后,如果您可以检查创建的三个列表dir_*
,或者仅检查完整列表和应删除的列表,您将看到类似以下内容的内容:
$ paste dir_list dir_list_del > list_formatted
$ awk ' BEGIN{printf "%-25s | %s\n","ALL","DELETE"; s=sprintf("%70s","");gsub(/ /,"-",s);print s}{printf "% -25s| %-s\n",$1,$2}' < list_formatted
ALL | DELETE
------------------------------------------------------------------------
!node_test3 | node_test2
node_test2 | node_test4
node_test4 |
node_test1 |
!node_test0 |
答案3
查找zsh
名称不包含!
且不包含.mp4
常规文件的目录:
set -o extendedglob
typeset -Ua dirs=(^*!*(N/^e['()(($#)) $REPLY/*.mp4(N.Y1)']))
删除!
包含最旧的 mp4 文件的目录(不包括名称中包含 的目录):
set -o extendedglob
rm -rf -- ^*!*/*.mp4(.om[1]:h)