이전 실행 중에 이미 처리된 파일 처리를 방지하는 방법은 무엇입니까?

이전 실행 중에 이미 처리된 파일 처리를 방지하는 방법은 무엇입니까?

다음은 정의된 경로의 모든 파일을 수정하는 스크립트입니다.

#!/bin/bash
FILES=/path/to/files/*
for f in $FILES
do
  [some_command_to_make_changes_into_file] $f > tmp_$f; mv tmp_$f $f
done

코드는 처음에는 잘 실행됩니다. 문제는 이 스크립트를 두 번째 또는 세 번째 실행할 때 모든 파일을 다시 선택한다는 것입니다. 내가 어떻게 할 수있는 진행되지 않았다마지막 실행에서 이미 처리된 모든 파일이 있습니까? 파일 이름이나 경로를 변경할 수 없습니다.

답변1

파일을 "처리됨"으로 표시할 수 있습니다.

#!/bin/bash
TAG="done"
FILES=/path/to/files/*
for f in $FILES
do
  case "$f" in
    *.$TAG) # process mark-files
      echo "# TAG-FILE=$f"
      b=`echo $f | sed "s/\.$TAG\$//"` # get base file of the mark-file
      echo "#   FILE=$b"
      if [ ! -f "$b" ] ; then
        echo "#  TAG-FILE REMOVE" 
        rm $f # remove mark-file without base file
      file
      continue # do not process mark-files themselves
      ;; 
  esac
  if [ -f "$f.TAG" ] ; then
    echo "# FILE=$f"
    echo "#   TAG-FILE PRESENT"
    continue # mark-file present - skip processing
  fi
  echo "# FILE=$f"
  echo "#   TAG-FILE ABSENT => PROCESSING"


  # [some_command_to_make_changes_into_file] $f > tmp_$f; mv tmp_$f $f

  echo "#   PROCESSED"
  touch "$f.$TAG" # create mark-file
  if [ -f "$f.TAG" ] ; then
    echo "#   TAG-FILE CREATED"
  else
    echo "#   TAG-FILE CREATION FAILED!"
    exit
  fi
done

가능한 개선 사항:태그 파일을 다른 디렉터리에 저장할 수 있습니다.

답변2

ext4등과 같은 최신 파일 시스템을 사용하는 경우 다음을 활용할 수 있습니다 btrfs.xfs확장된 파일 속성- 이 경우 "user" 네임스페이스 속성을 사용할 수 있습니다. 따라서 각 파일에 특정 속성이 있는지 확인합니다. 1 로 설정하면 파일을 건너뛰고, 그렇지 않으면 파일이 처리됩니다.그 다음에속성을 설정합니다. 속성과 그 값이 다음과 같이 정의되어 있다고 가정합니다.

user.validation="processed"

그러면 코드는 다음과 같은 작업을 수행할 수 있습니다.

for f in /path/to/files/*
  do
    if ! getfattr -n user.validation "$f" >/dev/null 2>&1
      then
        echo "$f"
        setfattr -n user.validation -v processed "$f"
    fi
  done

원하는 명령으로 바꾸세요 echo... 또한 결과를 확장하기 위해 glob을 반복하는 올바른 방법에 유의하세요. glob을 사용하거나 for결과를 배열에 저장하고 해당 요소를 반복합니다.

filez=( /path/to/files/* )
for f in "${filez[@]}"

1: 단순화를 위해 스크립트는 속성이 설정되어 있는지만 확인하고 해당 값은 확인하지 않습니다.

답변3

이것은 일부를 사용하는 좋은 예일 수 있습니다.자동화 구축유사한 도구암소 비슷한 일종의 영양make또는닌자,등...

예를 들어, 일부 입력 파일이 주어지면 이를 빈 태그 파일 로 변환 foo.txt할지 결정할 수 있습니다 (참조:foo.outtouchfoo.done안페이의 대답) 그리고 귀하의Makefile 이 모든 것에 대해. 그런데 이러한 태그(또는 로그) 파일은 다른 디렉터리에 있을 수 있습니다.

GNU make ( ninja등등...)는 항목을 컴파일하는 데 사용할 수 있을 뿐만 아니라 더 일반적으로 파일 타임스탬프를 기반으로 처리를 트리거하는 데 사용할 수 있습니다(일부 규칙을 채택한 경우).

그리고 make -j 4 이 처리를 위해 최대 4개의 작업을 병렬로 실행할 수 있으므로 대기 시간이 줄어듭니다.

답변4

make를 사용하여 다른 디렉토리에 "처리된" 태그 파일을 생성할 수 있습니다.

# version for gnu-make

# Path to directory with jobs files
DIR_JOBS=/path/to/files
# Path to directory with mark files marking processes job files
DIR_MARKS=/path/to/mark-files

JOBS=$(wildcard $(DIR_JOBS)/*)
MARKS=$(wildcard $(DIR_MARKS)/*)
JOBS_MARKS=$(patsubst $(DIR_JOBS)/%,$(DIR_MARKS)/%.done, $(JOBS))

$(DIR_MARKS)/%.done: $(DIR_JOBS)/%
        @echo '###' make $@ from $<
        # your command to process the job file - should return 0 on success
        touch $@

ALL: $(JOBS_MARKS)
        @echo '###' for debug purposes
        @echo JOBS=$(JOBS)
        @echo JOBS_MARKS=$(JOBS_MARKS)
        @echo MARKS=$(MARKS

관련 정보