以下は、定義されたパス内のすべてのファイルを変更するスクリプトです。
#!/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
などの最新のファイルシステムを使用している場合は、次のことを利用できます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.out
touch
foo.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