以前の実行中にすでに処理されたファイルの処理を防ぐ方法は?

以前の実行中にすでに処理されたファイルの処理を防ぐ方法は?

以下は、定義されたパス内のすべてのファイルを変更するスクリプトです。

#!/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

コードは最初はうまく動作します。問題は、このスクリプトを2回目または3回目の実行時にすべてのファイルを再選択することです。どうやってできるか 進まなかった最後の実行ですでに処理されているすべてのファイルはありますか?ファイル名やパスを変更できません。

答え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などの最新のファイルシステムを使用している場合は、次のことを利用できますbtrfsxfs拡張ファイル属性- この場合、「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 makeninja等...)は、アイテムをコンパイルするために使用できるだけでなく、より一般的にはファイルタイムスタンプに基づいて処理をトリガーするために使用できます(一部のルールを採用した場合)。

そして、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

関連情報