2012-03-19 58 views
0

我正在一個UNIX任務,我想檢查目錄中是否存在特定的日誌文件。如果它存在,我想通過在最後添加一個時間戳來重命名它。文件名的格式是這樣的:ServiceFileName_0.logUnix如果文件存在,重命名

這是我到目前爲止,但它不會重命名時,我運行該腳本,即使有一個文件的名稱ServiceFileName_0.log存在。

renameLogs() 
{ 
    #If a ServiceFileName log exists, rename it 

    if [ -f $MY_DIR/logs/ServiceFileName_0.log ]; 
    then 
    mv ServiceFileName_0.log ServiceFileName_0.log.%M%H%S 
    fi 
} 

請幫助!

感謝

+0

請點擊此處:http://theunixshell.blogspot.com/2013/01/bulk-renaming-of-files-in-unix.html – Vijay 2013-01-10 06:27:26

回答

1
renameLogs() 
{ 
    if [ -f $MY_DIR/logs/ServiceFileName_0.log ] 
    then mv $MY_DIR/ServiceFileName_0.log $MY_DIR/ServiceFileName_0.log.$(date +%M%H%S) 
    fi 
} 

使用

mv ServiceFileName_0.log ServiceFileName_0.log.%M%H%S 

目錄前綴始終堅持:

+0

謝謝。如果我想用一個字符串替換時間,這是否是正確的語法? mv $ MY_DIR/ServiceFileName_0.log $ MY_DIR/ServiceFileName_0.log。$(「Previous」)? – 2012-03-19 16:46:22

+0

符號$(「Previous」)'會執行命令'Previous'並在重命名過程中使用它的輸出。沒有做任何特別的事情,在你的原始文件中,備份將包含文字字符'%H%M%S';它們只對幾個命令有特殊意義,比如'date',這就是爲什麼我添加了'date'的調用。 – 2012-03-19 17:50:38

+0

非常感謝。很有幫助。我也有另一個文件,我必須重命名相同的方式,但文件名是ServiceFileName_1903.log。 1903年代表DDMM,明天將是2003年,2103年等。什麼是我可以放在IF語句中的通用參數,因爲這個數字每次都在變化 – 2012-03-19 18:09:15

3

您可能需要與$MY_DIR路徑前綴的文件名,就像你在測試一樣。與此

mv $MY_DIR/logs/ServiceFileName_0.log $MY_DIR/logs/ServiceFileName_0.log.%M%H%S 
0

您可以取代這一點。您還需要正確指定時間,如圖所示。

較好的,但(少重複):

renameLogs() 
{ 
    logfile="$MY_DIR/logs/ServiceFileName_0.log" 
    if [ -f "$logfile" ] 
    then mv "$logfile" "$logfile.$(date +%H%M%S)" 
    fi 
} 

注:我已經重新排序從MMHHSS格式,以更傳統的HHMMSS秩序。如果您也使用日期組件,則應認真考慮使用由ISO 8601推薦的[YYYY] mmdd的順序。它將ls列表中的所有日誌文件分組在一起,這通常很有用。使用ddmm命令意味着每個月的第一個文件被分組在一起,然後是每個月的第二個文件等。這通常不太理想。

0

這不是你明顯的直接問題,但if構造是錯誤的:它引入了time-of-check to time-of-use race conditionif [ -f檢查和mv之間,有些其他進程可能會出現並更改內容,因此即使檢查成功,您也無法再移動該文件。

要避免這類錯誤,請通過嘗試執行您想要執行的操作來始終編寫代碼,然後如果失敗,請找出原因。在這種情況下,如果源文件不存在,您希望什麼都不做,但如果由於任何其他原因導致操作失敗,則報告錯誤。在便攜式外殼中沒有好辦法做到這一點,你需要一些東西讓你檢查errno。我可能會寫該C幫手:

#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
int main(int argc, char **argv) 
{ 
    if (argc != 3) { 
     fprintf(stderr, "usage: %s source destination\n", argv[0]); 
     return 2; 
    } 
    if (rename(argv[1], argv[2]) && errno != ENOENT) { 
     fprintf(stderr, "rename '%s' to '%s': %s\n", 
       argv[1], argv[2], strerror(errno)); 
     return 1; 
    } 
    return 0; 
} 

,然後用它像這樣:

renameLogs() 
{ 
    (cd "$MY_DIR/logs" 
     rename_if_exists ServiceFileName_0.log ServiceFileName_0.log.$(date +%M%H%S) 
    ) 
} 

(cd結構修復立即解決問題,不像其他的建議,避免在另一個比賽哪些其他進程出現並與logs目錄或其父目錄混淆。

必需的shell腳本附錄:始終將變量擴展用雙引號括起來,除非在極少數情況下,您希望擴展受字分割。

相關問題