2012-03-19 4 views
0

특정 로그 파일이 디렉토리에 있는지 여부를 확인하려는 UNIX 작업을하고 있습니다. 그것이 존재하는 경우, 나는 끝에 타임 스탬프를 추가하여 이름을 바꾸고 싶습니다. 파일 이름의 형식은 다음과 같습니다. ServiceFileName_0.log유닉스 파일이 존재하는 경우, 이름 바꾸기

이것은 내가 지금까지 가지고 있지만 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 
} 

Pls 도움말! 당신은 $MY_DIR 경로와 파일 이름을 접두사해야 할 수도 있습니다

감사

+0

여기를 확인하십시오. http : //theunixshell.blogspot.com/2013/01/bulk-renaming-of-files-in-unix.html – Vijay

답변

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 
} 

사용하여 디렉토리의 접두사 일관합니다. 또한 그림과 같이 시간을 올바르게 지정해야합니다.

더 나은,하지만 (이하 반복) :

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

NB : 나는 더 많은 기존의 HHMMSS 순서에 MMHHSS에서 형식을 다시 정렬했습니다. 날짜 구성 요소로 작업하는 경우 ISO 8601에서 권장하는 [YYYY] mmdd의 주문 사용을 진지하게 고려해야합니다. 한 달 동안 모든 로그 파일을 ls 목록으로 그룹화합니다. 이는 일반적으로 도움이됩니다. ddmm 순서를 사용하면 매월 1 일에 대한 파일이 그룹으로 묶인 다음 매월 두 번째 파일로 그룹화됩니다. 이는 일반적으로 바람직하지 않습니다.

+0

감사합니다. 시간을 문자열로 바꾸고 싶다면 올바른 구문입니까? mv $ MY_DIR/ServiceFileName_0.log $ MY_DIR/ServiceFileName_0.log. $ ("Previous")? –

+0

'$ ("Previous") 표기법은'Previous' 명령을 실행하고 이름 변경 프로세스에서 출력을 사용합니다. 특별한 것을하지 않고 원래의 백업은 문자'% H % M % S'를 포함합니다; 'date'와 같은 몇 가지 명령에 대해서만 특별한 의미가 있습니다. 그래서'date'의 호출을 추가했습니다. –

+0

고맙습니다. 매우 도움이됩니다. 나 또한 같은 이름으로 바꾸어야하는 다른 파일이 있지만 파일 이름은 ServiceFileName_1903.log입니다. 1903은 DDMM을 나타내고 내일은 2003, 2103 등입니다. 숫자가 매번 변경되기 때문에 IF 문에 넣을 수있는 일반적인 인수는 무엇입니까 –

3

는 당신이 테스트에서했던 좋아한다.

0

당신은 이것을 대체 할 수있는 :

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

을이

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

이것은 명백한 즉각적인 문제는 아니지만 if 구조가 잘못 되었음 : time-of-check to time-of-use race condition을 소개합니다. if [ -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 디렉토리 또는 그 상위 디렉토리로 뒤범벅됩니다.

필수 쉘 스크립팅 부록 : 드문 경우를 제외하고는 확장을 단어 분할의 대상으로 삼는 경우를 제외하고 항상 변수 확장을 큰 따옴표로 묶으십시오.

관련 문제