bash脚本的基础上修改文件的日期删除目录 [英] bash script to remove directories based on modified file date

查看:304
本文介绍了bash脚本的基础上修改文件的日期删除目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待创造一个bash脚本,通过递归进入目录,并开始在树的尽头,按日期检查文件。如果最新的文件是超过90天,去了一个目录,然后检查同样的事情。如果没有新的文件超过90天,取出根目录。

例如的:


  

/ ftpdir /站点1 /资料夹/文件夹2


如果文件夹2没有新的文件,但文件夹1呢,删除文件夹,但是保持站点1

我在的AutoIt 这样写,但现在需要它作为一个bash脚本,我有点失落。

感谢

编辑:我以为我是清楚的,但让我澄清一些事情:


  1. 我不是在寻找通过FTP协议来做到这一点 - 这将运行作为日常cron作业

  2. 我的FTP站点被用作垃圾场。人们创建文件夹和子文件夹,从而填补了空间。大部分的东西被放弃。

  3. @乔纳森莱弗勒明白我想在这里做的。同样,我的混乱表示歉意。

  4. 我可以发表我原来的AutoIt脚本,显示什么,我试图完成。

编辑2 - 原来AutoIt脚本

 的#include< array.au3>
#包括LT&;&Date.au3 GT;
#包括LT&;&File.au3 GT;
#包括LT&;&GuiConstants.au3 GT;
#包括LT&;&GuiButton.au3 GT;
#包括LT&;&GuiListBox.au3 GT;
#包括LT&;&EditConstants.au3 GT;
#包括LT&;&ListBoxConstants.au3 GT;
#包括LT&;&WindowsConstants.au3 GT;
#包括LT&;&GuiListBox.au3 GT;
#包括LT&;&GuiMonthCal.au3 GT;
全球$文件夹名=\\\\ PH-SVR-web1的\\ ftpsites
全球$ rootFolder
全球现在$ = _Date_Time_SystemTimeToDateStr(_Date_Time_GetSystemTime(),1)
全球$ badSubs = 0,$ olderThan = 90
全球$ dirsToDeleteListBox,$ topIndex,$ TotalFoldersFound = 0
全球$ ScanFoldersButton,$ RemoveFoldersButton,$ TotalFoldersFoundLabel,$ TotalFoldersFoundNumber
全球$日历$ OlderThanNumberDays主要()FUNC的Main()
    $主窗口= GuiCreate(删除旧版文件从FTP站点,900)
    GUISetFont(12)    $ dirsToDeleteListBox = GUICtrlCreateList(,40,35,550,300,BITOR($ WS_BORDER,$ WS_VSCROLL,$ LBS_NOTIFY,$ LBS_DISABLENOSCROLL,$ WS_HSCROLL,$ LBS_EXTENDEDSEL))    $ ScanFoldersButton = GuiCtrlCreateButton(扫描FTP站点,40,330)
    $ RemoveFoldersButton = GUICtrlCreateButton(删除选定文件夹,180,330)
    _GUiCtrlButton_Enable($ RemoveFoldersButton,假)    $ TotalFoldersFoundLabel = GUICtrlCreateLabel(共文件夹找到=,400,335)
    $ TotalFoldersFoundNumber = GUICtrlCreateLabel($ TotalFoldersFound,560,335,100)    $日历= GUICtrlCreateMonthCal($主窗口,620,35,250,220);, $ MCS_NOTODAY)
    $ OlderThanDateLabel = GUICtrlCreateLabel(搜索前日期文件:630,270)
    GUISetFont(12,600)
    $ OlderThanDateValue = GUICtrlCreateLabel(SetCalendarDate($ olderThan),650,300)
    $ OlderThanNumberDays = GUICtrlCreateLabel((&安培; $ olderThan&安培;天),750,300,100)
    GUISetFont(12,400)    GUISetState()
    GUICtrlSetResizing($主窗口,513)    虽然1
        $ GUIAction = GuiGetMsg()
        开关$ GUIAction
            案例$ GUI_EVENT_CLOSE
                ExitLoop;关闭GUI
            案例$ ScanFoldersButton
                _GUICtrlButton_Enable($ ScanFoldersButton,假)
                _GUiCtrlButton_Enable($ RemoveFoldersButton,假)
                _GUICtrlListBox_ResetContent($ dirsToDeleteListBox)
                $ TotalFoldersFound = 0
                ScanFolder($文件夹名称)
                _GUICtrlButton_Enable($ ScanFoldersButton,真)
                如果$ TotalFoldersFound> 0,则
                    _GUiCtrlButton_Enable($ RemoveFoldersButton,真)
                    _GUICtrlListBox_SetTopIndex($ dirsToDeleteListBox,0)
                万一
            案例$ RemoveFoldersButton
                _GUICtrlButton_Enable($ ScanFoldersButton,假)
                _GUiCtrlButton_Enable($ RemoveFoldersButton,假)
                RemoveFolders()
                _GUICtrlButton_Enable($ ScanFoldersButton,真)
                _GUiCtrlButton_Enable($ RemoveFoldersButton,真)
            案例$日历
                GUICtrlSetData($ OlderThanDateValue,SetCalendarDate(_DateDiff('D',GUICtrlRead($日历),现在$)))
        endswitch
    WEND
ENDFUNCFUNC SetCalendarDate($天)
    $ newDate = _DateAdd('D', - ($天),$现在)
    GUICtrlSetData($日历$ newDate)
    $ olderThan = $天
    GUICtrlSetData($ OlderThanNumberDays,(与& $ olderThan&安培;天))
    返回$ newDate
ENDFUNCFUNC RemoveFolders()
    $ DIRS = _GUICtrlListBox_GetSelItemsText($ dirsToDeleteListBox)
    开关$迪尔斯[0]
        案例0
            MSGBOX(276,没有选择文件夹,请选择文件夹删除)
        否则案例
            ProgressOn(删除FTP文件夹...,删除)
            $ totalDirs = UBound函数($迪尔斯) - 1
            为$ II = 1至$ totalDirs
                DirRemove($迪尔斯[$ II],1)
                ProgressSet((100 / $ totalDirs),$迪尔斯[$ II])
                $ removeFromList = _GUICtrlListBox_FindString($ dirsToDeleteListBox,$迪尔斯[$ II])
                如果$ removeFromList> 0,则
                    _GUICtrlListBox_BeginUpdate($ dirsToDeleteListBox)
                    _GUICtrlListBox_DeleteString($ dirsToDeleteListBox,$ removeFromList)
                    _GUICtrlListBox_EndUpdate($ dirsToDeleteListBox)
                    $ TotalFoldersFound - = 1
                    GUICtrlSetData($ TotalFoldersFoundNumber,$ TotalFoldersFound)
                万一
            下一个
            ProgressOff()
            MSGBOX(64文件夹中删除,选定的文件夹已被删除)
    EndSwitch
ENDFUNCFUNC ScanFolder($ SourceFolder)
    本地搜索$
    本地文件$
    当地$ FileAttributes
    当地$ FullFilePath
    当地$ FILEDATE    $搜索= FileFindFirstFile($ SourceFolder&安培;\\ *。*)    虽然1
        如果$搜索= -1然后
            ExitLoop
        万一        $文件= FileFindNextFile($搜索)
        如果@error然后ExitLoop        $ FullFilePath = $ SourceFolder&安培; (\\&放大器; $文件)
        $ FileAttributes = FileGetAttrib($ FullFilePath)
        $ FILEDATE = _ArrayToString(FileGetTime($ FullFilePath),/,0,2)
        $ validRoot = ExtractRoot($ FullFilePath)
        如果StringInStr($ FileAttributes,D)。然后
            如果$ validRoot> = 6则
            选择
                案例_DateDiff('D',$ FILEDATE,现在$)< = $ olderThan
                    $ badSubs + = 1
                    continuecase
                情况下StringCompare($ rootFolder,$ FullFilePath)= 0
                    如果$ badSubs = 0,则
                        _GUICtrlListBox_BeginUpdate($ dirsToDeleteListBox)
                        $ topIndex = _GUICtrlListBox_AddString($ dirsToDeleteListBox,$ rootFolder)
                        _GUICtrlListBox_SetTopIndex($ dirsToDeleteListBox,$ topIndex)
                        _GUICtrlListBox_EndUpdate($ dirsToDeleteListBox)
                        $ TotalFoldersFound + = 1
                    其他
                        $ removeFromList = _GUICtrlListBox_FindString($ dirsToDeleteListBox,$ rootFolder)
                        如果$ removeFromList> = 0则
                            _GUICtrlListBox_BeginUpdate($ dirsToDeleteListBox)
                            _GUICtrlListBox_DeleteString($ dirsToDeleteListBox,$ removeFromList)
                            _GUICtrlListBox_SetTopIndex($ dirsToDeleteListBox,$ topIndex)
                            _GUICtrlListBox_EndUpdate($ dirsToDeleteListBox)
                            $ TotalFoldersFound - = 1
                        万一
                        $ badSubs = 0
                    万一
            ENDSELECT
            GUICtrlSetData($ TotalFoldersFoundNumber,$ TotalFoldersFound)
            万一
            ScanFolder($ FullFilePath)
        万一
    WEND    FILECLOSE($搜索)
ENDFUNCFUNC ExtractRoot($文件名)
    $ dirArray = StringSplit($文件名,\\)
    如果$ dirArray [0]> = 6则
        $ rootFolder = _ArrayToString($ dirArray,\\,1,6)
    万一
    返回$ dirArray [0]
ENDFUNC

编辑3:

感谢罗布,我修改他的剧本我的需求如下:

 #! /斌/庆典如果[-z$ 1];
然后
    回声你必须在脚本名称后输入路径
    出口
科幻#用法:ThisProgram /路径/到/根/的/文件迪尔斯=($(发现$ {1}-maxdepth 1型ð-print | sed的的:^ / ::。'))
回声$ 1在$ {迪尔斯[@]}目录;做如果[$ DIR = $ 1!]。然后
    回声$目录
#首先,获得所有子目录的列表,以深度优先顺序
找到$ {DIR: - }-depth型Ð-print0 |
而读-r -d'我
做  #对于每个子目录,测试以查看它是否匹配两个条件。如果任
  #条件失败,这个子目录不是删除的候选。
#回声试图$ I  #第一:它是在最低水平,即它有任何幸存的孩子吗?
  [$(发现$ I型Ð-print |厕所-l)-gt 1]安培;&安培;继续
#回声$ i有没有子目录  #第二:它有任何最新的文件?
  [$(发现$ I型的F -90 -mtime |厕所-l)-gt 0]放大器;&安培;继续
#回声$ i有没有新文件  #如果我们来到这里,那么这个考生没有子目录,并没有新的文件。 NUKE它。
#回声室射频$ I
  回声$ I
#室射频$ I
DONE科幻


解决方案

 #! /斌/庆典#用法:ThisProgram /路径/到/根/的/文件
#如果来的/文件/根/ /路径/未指定,使用当前目录来代替。#首先,获得所有子目录的列表,以深度优先顺序
找到$ {1: - 。}-depth型Ð-print0 |
而读-r -d'我
做  #对于每个子目录,测试以查看它是否匹配两个条件。如果任
  #条件失败,这个子目录不是删除的候选。
  回声$尝试我  #第一:它是在最低水平,即它有任何幸存的孩子吗?
  [$(发现$ I型Ð-print |厕所-l)-gt 1]安培;&安培;继续
  回声$ i有没有子目录  #第二:它有任何最新的文件?
  [$(发现$ I型的F -90 -mtime |厕所-l)-gt 0]放大器;&安培;继续
  回声$ i有没有新文件  #如果我们来到这里,那么这个考生没有子目录,并没有新的文件。 NUKE它。
  回声室射频$ IDONE

I'm looking to create a bash script that recursively goes through directories and, starting at the very end of the tree, examines the files by date. If the newest file is older than 90 days, go up one directory and check the same thing. If there are no files newer than 90 days, remove the root directory.

example :

/ftpdir/Site1/folder1/folder2

if folder 2 has no newer files, but folder 1 does, remove folder one, but keep Site1

I've written this in AutoIT, but now need it as a bash script and I'm a bit lost.

Thanks

EDIT: I thought I was being clear, but let me clarify a few things:

  1. I'm not looking to do this through the FTP protocol - this would run as a daily cron job
  2. My FTP site is used as a dumping ground. People create folders and subfolders, which in turn fills up space. Most of the stuff is abandoned.
  3. @Jonathan Leffler understands what I'm trying to do here. Again, I apologize for the confusion.
  4. I can post my original AutoIT script that shows what I'm trying to accomplish.

EDIT 2 - the original AutoIT script

#include <array.au3>
#include <Date.au3>
#include <File.au3>
#include <GuiConstants.au3>
#include <GuiButton.au3>
#Include <GuiListBox.au3>
#include <EditConstants.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiListBox.au3>
#Include <GuiMonthCal.au3>


Global $FolderName = "\\ph-svr-web1\ftpsites"
Global $rootFolder
Global $now = _Date_Time_SystemTimeToDateStr(_Date_Time_GetSystemTime(), 1) 
Global $badSubs = 0, $olderThan = 90
Global $dirsToDeleteListBox, $topIndex, $TotalFoldersFound = 0
Global $ScanFoldersButton, $RemoveFoldersButton, $TotalFoldersFoundLabel, $TotalFoldersFoundNumber
Global $Calendar, $OlderThanNumberDays

Main()

Func Main()
    $MainWindow = GuiCreate("Remove Older Files From FTP Site", 900)
    GUISetFont(12)

    $dirsToDeleteListBox = GUICtrlCreateList("", 40, 35, 550, 300, BitOr($WS_BORDER, $WS_VSCROLL, $LBS_NOTIFY, $LBS_DISABLENOSCROLL, $WS_HSCROLL, $LBS_EXTENDEDSEL))

    $ScanFoldersButton = GuiCtrlCreateButton("Scan FTP Site", 40, 330)
    $RemoveFoldersButton = GUICtrlCreateButton("Delete Selected Folders", 180, 330)
    _GUiCtrlButton_Enable($RemoveFoldersButton, False)

    $TotalFoldersFoundLabel = GUICtrlCreateLabel("Total Folders Found = ", 400, 335)
    $TotalFoldersFoundNumber = GUICtrlCreateLabel($TotalFoldersFound, 560, 335, 100)

    $Calendar = GUICtrlCreateMonthCal($MainWindow, 620, 35, 250, 220);, $MCS_NOTODAY)
    $OlderThanDateLabel = GUICtrlCreateLabel("Searching for files dated prior to:", 630, 270)
    GUISetFont(12, 600)
    $OlderThanDateValue = GUICtrlCreateLabel(SetCalendarDate($olderThan), 650, 300)
    $OlderThanNumberDays = GUICtrlCreateLabel("(" & $olderThan & " days)", 750, 300, 100)
    GUISetFont(12, 400)

    GUISetState()
    GUICtrlSetResizing ($MainWindow, 513 )

    While 1
        $GUIAction = GuiGetMsg()
        Switch $GUIAction
            Case $GUI_EVENT_CLOSE
                ExitLoop ; closes the GUI
            Case $ScanFoldersButton
                _GUICtrlButton_Enable($ScanFoldersButton, False)
                _GUiCtrlButton_Enable($RemoveFoldersButton, False)
                _GUICtrlListBox_ResetContent($dirsToDeleteListBox)
                $TotalFoldersFound = 0
                ScanFolder($FolderName)
                _GUICtrlButton_Enable($ScanFoldersButton, True)
                if $TotalFoldersFound > 0 then
                    _GUiCtrlButton_Enable($RemoveFoldersButton, True)
                    _GUICtrlListBox_SetTopIndex($dirsToDeleteListBox, 0)
                endif
            Case $RemoveFoldersButton
                _GUICtrlButton_Enable($ScanFoldersButton, False)
                _GUiCtrlButton_Enable($RemoveFoldersButton, False)
                RemoveFolders()
                _GUICtrlButton_Enable($ScanFoldersButton, True)
                _GUiCtrlButton_Enable($RemoveFoldersButton, True)
            Case $Calendar
                GUICtrlSetData($OlderThanDateValue, SetCalendarDate(_DateDiff('D', GUICtrlRead($Calendar), $now)))
        endswitch
    wend
EndFunc

Func SetCalendarDate($Days)
    $newDate = _DateAdd('D', -($Days), $now)
    GUICtrlSetData($Calendar, $newDate)
    $olderThan = $Days
    GUICtrlSetData($OlderThanNumberDays, "(" & $olderThan & " days)")
    Return $newDate
EndFunc

Func RemoveFolders()
    $Dirs = _GUICtrlListBox_GetSelItemsText($dirsToDeleteListBox)
    Switch $Dirs[0]
        Case 0
            MsgBox(276,"No folders selected","Please select folders to delete")
        Case Else
            ProgressOn("Deleting FTP Folders...", "Removing")
            $totalDirs = UBound($Dirs) - 1
            for $iI = 1 to $totalDirs
                DirRemove($Dirs[$iI], 1)
                ProgressSet((100 / $totalDirs), $Dirs[$iI])
                $removeFromList = _GUICtrlListBox_FindString($dirsToDeleteListBox, $Dirs[$iI])
                if $removeFromList > 0 then 
                    _GUICtrlListBox_BeginUpdate($dirsToDeleteListBox)
                    _GUICtrlListBox_DeleteString($dirsToDeleteListBox, $removeFromList)
                    _GUICtrlListBox_EndUpdate($dirsToDeleteListBox)
                    $TotalFoldersFound -= 1
                    GUICtrlSetData($TotalFoldersFoundNumber, $TotalFoldersFound)
                endif
            next
            ProgressOff()
            MsgBox(64, "Folders Deleted", "The selected folders have been deleted")
    EndSwitch
EndFunc

Func ScanFolder($SourceFolder)
    Local $Search
    Local $File
    Local $FileAttributes
    Local $FullFilePath
    Local $FileDate

    $Search = FileFindFirstFile($SourceFolder & "\*.*")

    While 1
        If $Search = -1 Then
            ExitLoop
        EndIf

        $File = FileFindNextFile($Search)
        If @error Then ExitLoop

        $FullFilePath = $SourceFolder & ("\" & $File)
        $FileAttributes = FileGetAttrib($FullFilePath)
        $FileDate = _ArrayToString(FileGetTime($FullFilePath), "/", 0, 2)
        $validRoot = ExtractRoot($FullFilePath)


        If StringInStr($FileAttributes,"D") Then
            if $validRoot >= 6 then
            select
                case _DateDiff('D', $FileDate, $now) <= $olderThan
                    $badSubs += 1
                    continuecase
                case StringCompare($rootFolder, $FullFilePath) = 0
                    if $badSubs = 0 then
                        _GUICtrlListBox_BeginUpdate($dirsToDeleteListBox)
                        $topIndex = _GUICtrlListBox_AddString($dirsToDeleteListBox, $rootFolder)
                        _GUICtrlListBox_SetTopIndex($dirsToDeleteListBox, $topIndex)
                        _GUICtrlListBox_EndUpdate($dirsToDeleteListBox)
                        $TotalFoldersFound += 1
                    else
                        $removeFromList = _GUICtrlListBox_FindString($dirsToDeleteListBox, $rootFolder)
                        if $removeFromList >= 0 then 
                            _GUICtrlListBox_BeginUpdate($dirsToDeleteListBox)
                            _GUICtrlListBox_DeleteString($dirsToDeleteListBox, $removeFromList)
                            _GUICtrlListBox_SetTopIndex($dirsToDeleteListBox, $topIndex)
                            _GUICtrlListBox_EndUpdate($dirsToDeleteListBox)
                            $TotalFoldersFound -= 1
                        endif
                        $badSubs = 0
                    endif
            endselect
            GUICtrlSetData($TotalFoldersFoundNumber, $TotalFoldersFound)
            endif
            ScanFolder($FullFilePath)
        EndIf
    Wend

    FileClose($Search)
EndFunc

Func ExtractRoot($FileName)
    $dirArray = StringSplit($FileName, "\")
    if $dirArray[0] >= 6 then
        $rootFolder = _ArrayToString($dirArray, "\", 1, 6)
    endif
    return $dirArray[0]
EndFunc

Edit 3:

Thanks to Rob, I've modified his script to my needs as follows:

#! /bin/bash

if [ -z "$1" ];
then
    echo "You must enter a path after the script name"
    exit
fi

# Usage: "ThisProgram /path/to/root/of/files"

dirs=( $(find "${1}" -maxdepth 1 -type d -print | sed 's:^./::'))
echo "$1"

for dir in "${dirs[@]}"; do

if [ $dir != $1 ]; then
    echo "$dir"
# First, get a list of all subdirs, in depth-first order
find "${dir:-.}" -depth -type d -print0 |
while read -r -d '' i
do

  # For each subdir, test to see if it matches two conditions. If either
  # condition fails, this subdir is not a candidate for deletion.
#  echo "Trying $i"

  #  First: is it at the lowest level, i.e. does it have any surviving children?
  [ "$(find "$i" -type d -print | wc -l)" -gt 1 ] && continue
#  echo "$i has no subdirs"

  # Second: does it have any recent files?
  [ "$(find "$i" -type f -mtime -90 | wc -l)" -gt 0 ] && continue
#  echo "$i has no new files"

  # If we got here, then this candidate has no subdirs and no recent files. Nuke it.
#  echo rm -rf "$i"
  echo "$i"
#  rm -rf "$i"
done

fi

解决方案

#! /bin/bash

# Usage: "ThisProgram /path/to/root/of/files"
# If "/path/to/root/of/files" is not specified, use the current directory instead.

# First, get a list of all subdirs, in depth-first order
find "${1:-.}" -depth -type d -print0 |
while read -r -d '' i 
do

  # For each subdir, test to see if it matches two conditions. If either
  # condition fails, this subdir is not a candidate for deletion.
  echo "Trying $i"

  #  First: is it at the lowest level, i.e. does it have any surviving children?
  [ "$(find "$i" -type d -print | wc -l)" -gt 1 ] && continue
  echo "$i has no subdirs"

  # Second: does it have any recent files?
  [ "$(find "$i" -type f -mtime -90 | wc -l)" -gt 0 ] && continue
  echo "$i has no new files"

  # If we got here, then this candidate has no subdirs and no recent files. Nuke it.
  echo rm -rf "$i"

done

这篇关于bash脚本的基础上修改文件的日期删除目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆