我正在寻找创建一个bash脚本,递归地通过目录,并从最后的树开始,按日期检查文件。如果最新的文件大于90天,请上传一个目录并检查相同的内容。如果没有比90天更新的文件,请删除根目录。bash脚本根据修改的文件日期删除目录
例如:
/ftpdir /站点1/folder1中/文件夹2
如果文件夹2不具有较新的文件,但文件夹1确实除去夹之一,但保持站点1
我已经写过这个AutoIT
,但现在需要它作为bash脚本,我有点失落。
感谢
编辑:我想我是清楚的,但让我澄清一些事情:
- 我不是在寻找通过FTP协议来做到这一点 - 这将运行作为每日cron工作
- 我的FTP站点被用作垃圾场。人们创建文件夹和子文件夹,这反过来填补了空间。大部分东西都被抛弃了。
- @Jonathan Leffler了解我在这里要做什么。再次,我对这种混乱表示歉意。
- 我可以发布我的原始AutoIT脚本,显示我正在尝试完成。
EDIT 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
什么问题?这没有多大意义。如果其最新文件大于90天并且其父目录也没有比90天更新的文件,则删除目录:S为什么?明确你想要做什么。如果folder1有两个subdirs会发生什么?删除目录的条件是什么? – c00kiemon5ter
把它想象成一个包含关于“事件”的保存电子邮件的目录,每个电子邮件包含一个文件。如果最近的消息已超过90天,则事件结束并结束,并且可以删除整个目录。如果任何消息少于90天,请将所有文件保存在目录中;事件仍然“活跃”,我们需要所有的信息。该示例使用FTP。它仍然令人困惑地描述。 –
原始问题中的编辑 –