Удалить каталоги, содержащие определенный файл, за исключением каталогов, начинающихся с "!"

Вы можете удалить папку по индексному узлу.

Сначала найдите номер инода с помощью ls -ial Antonin_Dvorak/.

Пример вывода:

$ ls -ial Antonin_Dvorak/
total 12
25306387 drwx------ 3 VUW\me VUW\domain users 4096 Jan 22  2015 /
23592962 drwx------ 3 VUW\me VUW\domain users 4096 Jan 22  2015./
23592391 drwx------ 3 VUW\me VUW\domain users 4096 Aug 25 11:10../

Вы не можете напрямую передать индексный дескриптор rm, но есть хитрость с find.

find. -maxdepth 1 -type d -inum 25306387 -delete

Убедитесь, что вы заменили мой образец inode (25306387 )на тот, что есть в вашей системе!

2
20.11.2019, 23:07
2 ответа

Внутри скрипта, где !расширение истории отключено по умолчанию, вы должны иметь возможность сопоставлять каталоги, имена которых не содержат !, используя простой глобус оболочки :либо *[^!]*, либо*[!!]*(в первый из которых !является отрицанием POSIX ).

Существует несколько способов проверки условия «каталоги, не содержащие *.mp4»; один из них, который приходит на ум, — это использовать другой глобус со встроенной оболочкой setи проверить полученное количество позиционных параметров $#.

Собираем вместе:

#!/bin/bash

shopt -s nullglob

for d in./*[^!]*/; do
  set -- "$d"/*.mp4
  if [ $# -eq 0 ]; then
    printf '%s\n' "$d"
  fi
done

Этот подход должен работать в интерактивной оболочке, если вы либо отключите расширение истории, либо экранируете символ !в th glob, т.е.*[^\!]*


Обратите внимание, :ваш заголовок относится к каталогам, начинающимся с «!» но в тексте вы упоминаете каталоги, содержащие "!" . Я предположил последний случай, но если вы хотите исключить только первый, удалите начальный *из глобуса.

2
27.01.2020, 22:02

Прежде всего, я думаю, что ваш подход очень опасен, потому что вы ищете и основываете операцию удаления на результатах чего-то не найденного. Было бы намного безопаснее и выгоднее, если бы вы добавили эту проверку к скрипту, который проверяет и удаляет самый старый файл 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              | 

1
27.01.2020, 22:02

Теги

Похожие вопросы