2017-02-20 18 views
2

Я только я на самом деле этот скрипт тестированияBASH Script - Удаление папки старше X дней для некоторых и все их подпапок/файлов

find /Path/Folder/* -type d -mtime +7 ! -path "/Path/Folder/NODELETE1/*" ! -path "/Path/Folder/NODELETE2/*" ! -path "/Path/Folder/NODELETE3/*" -exec rm -rf {} \; 

удалить все файлы/папки старше 7 дней за NODELETE1 исключением, NODELETE2 и NODELETE3 папки.

Проблема в том, что она, по-видимому, не работает, из-за этого удаляются эти папки и все файлы внутри.

Это то, что я хочу сделать:

У меня есть

/Path/Folder/NODELETE1/some files and folders 
/Path/Folder/NODELETE2/some files and folders 
/Path/Folder/NODELETE3/some files and folders 
/Path/Folder/AFOLDER/somefiles and folders 
/Path/Folder/ANOTHERFOLDER/somefiles and folders 
/Path/Folder/... 
/Path/Folder/FILE 
/Path/Folder/ANOTHERFILE 
/Path/Folder/... 

Я хочу, чтобы автоматически удалить все файлы и папки старше, что 7 дней (так FOLDER, ANOTHERFOLDER, ..., FILE, ANOTHERFILE, ...) так, чтобы

/Path/Folder/NODELETE1/some files and folders 
/Path/Folder/NODELETE2/some files and folders 
/Path/Folder/NODELETE3/some files and folders 

Что случилось с сценарием?

EDIT с предложением сценария:

#!/bin/bash 

while IFS= read -r -d '' dir 
do 

    # This line actually halts the control from entering if 
    # dirname contains either of the three names below. You could 
    # remove it and put your actual folder names. 

    [[ $dir =~ ^(NODELETE1|NODELETE2|NODELETE3)$ ]] && continue 

    # Suggest un-commenting the echo line below and comment rm to ensure 
    # you have only the folders you want to delete. 
    echo "$dir" 

    # rm -rf "$dir"  
done< <(find /Users/Username/Desktop/test/* -type d -mtime +7 -print0) 

Для тестирования у меня есть:

/Users/Username/Desktop/test/NODELETE1 
/Users/Username/Desktop/test/NODELETE2 
/Users/Username/Desktop/test/NODELETE3 
/Users/Username/Desktop/test/YESDELETE 

и путь сценария

/Users/Username/Desktop/TEST.sh 
+0

Можете ли вы попробовать '-not -path '/ Path/Folder/NODELETE1/*" 'вместо'! -path "/ Path/Folder/NODELETE1/*" ' – Inian

+1

Только я страдаю от паранойи и никогда не буду запускать' rm -rf' непосредственно в качестве аргумента 'find -exec'? :) – jm666

+0

@ jm666: То же самое здесь, поэтому предложил альтернативу с правильной проверкой имени – Inian

ответ

2

TL; DR Fix:

Вместо вашей линии, сделайте следующее:

find /Path/Folder/* -type d -mtime +7 ! -path "/Path/Folder/NODELETE1" ! -path "/Path/Folder/NODELETE2" ! -path "/Path/Folder/NODELETE3" -exec rm -rf {} \; 

Longer объяснение:

-типа d часть вашей линии поиск только каталоги. Но то, что вы исключаете, - это вещи в ваших каталогах NODELETE. Это по-прежнему означает, что ваши каталоги NODELETE являются целями для rm -rf и благодаря этому они получают рекурсивно удаленные.

+1

Он отлично работает! – DylanDog

1

Побег! в

\! -path 

, чтобы убедиться, что она не будет истолковано как шаблон

2

Вместо того, чтобы полагаться на основные утилитами командования find, я предложил бы позволить bash заботиться о нем (вы отметили bash во всяком случае), чтобы исключить папки, имеющие конкретные имена,

#!/bin/bash 

while IFS= read -r -d '' dir 
do 

    # This line actually halts the control from entering if 
    # dirname contains either of the three names below. You could 
    # remove it and put your actual folder names. 

    [[ $dir =~ ^(NODELETE1|NODELETE2|NODELETE3)$ ]] && continue 

    # Suggest un-commenting the echo line below and comment rm to ensure 
    # you have only the folders you want to delete. 
    # echo "$dir" 

    rm -rf "$dir"  
done< <(find /Path/Folder/* -type d -mtime +7 -print0) 
+0

Это дает мне эту ошибку 'строка 17: синтаксическая ошибка около неожиданного токена' <'''/Users/Username/Desktop/TEST.sh: строка 17: 'done <<(find/Users/Username/Desktop/test/* -type d -mtime +7 -print0) '' – DylanDog

+0

@DylanDog: Вы используете его с набором интерпретаторов bash? '#!/bin/bash' в верхней части скрипта? – Inian

+0

yes '#!/Bin/bash' – DylanDog