2014-09-15 2 views
0

파일을 입력으로 가져 와서 파일의 각 행을 읽고 해당 행에서 작업을 수행하는 bash 스크립트가 있습니다. 아래 예제에서는 각 줄을 인쇄하고 있습니다. 내가하고 싶은 것은 while 루프에서 내 위치를 추적하는 것이다. 그래서 어떤 일이 생기면 (예를 들어 컴퓨터 충돌), 스크립트를 다시 시작하여 while 루프에서 다시 시작하지 않고 while 루프를 계속할 수있다. 처음. 나는 현재 로그 파일 (어느 파일의 어느 줄을 추적하고 있는지)에 진행 상황을 인쇄하고 있으며, 마지막으로 완료된 루프 위치 (로그 파일이 없으면 0)를 얻기 위해 자동으로 읽히지 만, 내 while 루프를 처음부터 시작하는 것이 아니라이 시점부터 시작하는 방법을 모르겠다. 어떤 도움을 주시면 감사하겠습니다. 난 당신이 추구하는 read을 얻을 수 있다고 생각하지 않습니다bash 스크립트에서 마지막 위치의 루프를 다시 시작하십시오.

#!/bin/bash 

while getopts ":l:" o; do 
    case "${o}" in 
     l) 
      l=${OPTARG} # input file 
      ;; 
    esac 
done 
shift $((OPTIND-1)) 

if [ ! -f ./log.txt ]; then 
    position=0 
    printf "Starting from beginning of file\n"; 
else 
    position=$(head log.txt) 
    printf "Starting on line ${position}\n"; 
fi 

while read line; do 
    printf "WORKING on line ${line}\n" 
    printf "$position\n" > log.txt 
    let position=position+1 
done < ${l} 

답변

1

그렇게 간단한 솔루션은 이미 계속하는 대신 작업을 수행하여 본 적이 줄을 while 루프의 상단에 위치 확인을 고수하고 구울 수 있습니다.

또한 대용량 로그 파일의 경우 데이터의 상당 부분을 처리하는 데 비용이 적게 드는 경우 원시 파일 대신 입력 대신에 프로세스 대체를 사용하고 tail -+$position으로 파일을 검색하는 것이 좋습니다.

@rici는 로그 파일의 내용이 예상 한 것과 다를 수 있으므로 파일을 맹목적으로 사용하지 않고 원하는 내용과 내용 만 포함하고 있는지 확인해야합니다.

+0

감사합니다. Etan. while 루프의 위치 확인은 충분히 쉽게 작동합니다. 왜 내가 그렇게 생각하지 않았는지 모르겠다. – James

+3

@ user3182448 : 필자는 개인적으로 마지막 행을'done <$ {1}'에서'done <(tail -n + $ position "$ 1")'로 바꾸는 옵션 2로 갈 것입니다. 로그 파일을 만들 때 많은 경쟁 조건이 있으며 충돌이 발생하는 비율이 적어도있는 경우 로그 파일이 비어 있기 때문에이 전략으로 복구 할 수 없습니다. ('> log'은 먼저 파일을 잘라내어 그 파일에 쓰고, truncate 후에 크래쉬가 발생하고 쓰기가 플러시되기 전에 ....) – rici

+1

'printf "$ position \ n"> tmp-log.txt && mv tmp-log.txt log.txt'는'mv'가 원자 적이며'log.txt'가 업데이트되었거나 변경되지 않았 음을 보장하기 때문에 주로 경쟁 조건을 수정합니다. – chepner

관련 문제