Scripting

使用 find 和 exec 提高腳本的性能

  • January 11, 2019

我有一個腳本,它遍歷給定目錄並自動壓縮那些不包含至少一個在不到 30 天內使用的文件的文件。現在,我想知道是否可以通過將 find 與 exec 一起使用來提高性能。我嘗試了一些東西,但它不起作用。你有什麼建議嗎?

#!/bin/bash
# find all the directories
dirs=`find . -type d`
# iterate every file in every directory
for dir in $dirs
do
       n="totar"
       # search all the file in the directory
       files=`find $dir -type f -atime -30`
       for file in $files
       do
               n="keepasis"
       done
       if [ $n == "totar" ]; then
               tar -zcvf $dir.tgz $dir
               rm -r $dir
       fi
done

我的想法是用類似的東西替換第二個 for 循環:

find $dir -type f -atime -30 -exec n="keepasis" {} \;

如果您在find’ 的-exec操作中設置變數,這將不可見。

找到文件並列印其名稱的事實find足以決定您不想歸檔該目錄。所以你不需要for file in $files循環,而是檢查它$files不為空。

如果您的find命令支持該-quit操作,您可以使用它在第一次匹配後停止。(見第一次匹配後如何停止查找命令?

與其將第一個輸出find放入變數中並使用帶有分詞的 for 循環,不如find逐行讀取 ’ 的輸出石灰。

#!/bin/bash
# find all the directories
# -mindepth 1 prevents "find" from printing "."
find . -mindepth 1 -type d | while read -r dir
do
   # a subdirectory might no longer exist if a parent has been archived before
   if [ -d "$dir" ]
   then
       # search any new file in the directory
       newfilefound=`find $dir -type f -atime -30 -print -quit`

       if [ -z "$newfilefound" ]
       then
           tar -zcvf $dir.tgz $dir
           rm -r $dir
       fi
  fi
done

如果您使用的是 bash,您可以改進第一個find以正確處理帶有特殊字元的更多目錄名稱:find . -type d -print0 | while IFS= read -r -d '' dir; do

還有一個性能問題:

如果一個目錄在子目錄的某處包含一個新文件,則不要刪除它。稍後,您將獲得所有子目錄名稱,直到包含此文件的名稱。在這種情況下,您將使用find多次來找到相同的新文件。

我想到的唯一解決方案是使用兩個find,一些後處理和一個fgrep

  1. 讓我們find列印所有新文件的名稱,通過刪除文件名來處理輸出,將所有父目錄列印為單獨的行並刪除重複項並將列表放入文件 NEWDIRS.
  2. 第二次find將所有目錄名列印到第二個文件 ALLDIRS.
  3. 用於fgrep查找 ALLDIRS 中與 NEWDIRS 中的行不匹配的所有行。

在刪除目錄之前,您應該檢查該tar命令是否成功。

引用自:https://unix.stackexchange.com/questions/493778