微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux-bash脚本根据修改后的文件日期删除目录

我正在寻找创建一个bash脚本,该脚本以递归方式遍历目录,并从树的最末端开始按日期检查文件.如果最新文件的日期超过90天,请转到一个目录并检查相同的内容.如果没有超过90天的文件,请删除根目录.

例如:

/ftpdir/Site1/folder1/folder2

如果文件夹2没有较新的文件,但是文件夹1有,则删除文件夹1,但保留Site1

我已经在AutoIT中编写了此代码,但现在需要将其作为bash脚本使用,我有点迷失了.

谢谢

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

>我不希望通过FTP协议执行此操作-这将作为日常cron工作运行
>我的FTP站点被用作垃圾场.人们创建文件夹和子文件夹,这些文件夹和子文件夹又占满了空间.大部分东西都被遗弃了.
> @Jonathan Leffler了解我在这里要做的事情.再次,我对此感到抱歉.
>我可以发布原始的AutoIT脚本,以显示我要完成的工作.

编辑2-原始的AutoIT脚本

#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

编辑3:

多亏了Rob,我对他的脚本进行了如下修改

#! /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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐