这是一个修改定义路径中所有文件的脚本:
#!/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
您可以利用扩展文件属性- 在这种情况下,您可以使用“用户”名称空间属性。因此,检查每个文件的特定属性 - 如果设置为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
答案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