删除包含某个文件的目录(以“!”开头的目录除外)

删除包含某个文件的目录(以“!”开头的目录除外)

我正在尝试按照标题所述进行操作。我有一台服务器,每天轮换电影列表,而我的存储空间不足。我有一个脚本可以遍历并删除最旧的 .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)

相关内容