我的目录中有多个冲突文件,我正在寻找一种方法,根据文件的名称和大小,根据不同的模式对重复项进行排序、命名和删除。虽然我对 bash 脚本的了解非常有限,但我正在寻找有关如何创建此脚本的任何指导。
- 可以通过文件名和文件大小来区分重复项
- 如果有重复,文件名以 _conflict-yyyymmdd-hhmmss.ext 结尾
- 该文件总是有一个无前缀的版本,但这可能是损坏的
- 最大尺寸的文件始终是正确的
- 多个文件可以具有相同的大小,在这种情况下,删除重复项并重命名文件是最理想的
- 结束文件应该始终没有前缀
以下是可能出现的情况的示例:
FILE SIZE DESIRED ACTION
a. /path/to/dir1/FileName1.ext 0 rm
b. /path/to/dir1/FileName1_conflict-20130324-231953.ext 21624832 mv b a
c. /path/to/dir1/FileName1_conflict-20130326-080529.ext 21624832 rm
a. /path/to/dir2/FileName2.ext 25432935 -
b. /path/to/dir2/FileName2_conflict-20130324-092544.ext 0 rm
c. /path/to/dir2/FileName2_conflict-20130326-212307.ext 25432935 rm
a. /path/to/dir3/FileName3.ext 0 rm
b. /path/to/dir3/FileName3_conflict-20130324-214501.ext 23422234 mv b a
a. /path/to/dir4/FileName4.ext 0 rm
b. /path/to/dir4/FileName4_conflict-20130324-110541.ext 14423 rm
c. /path/to/dir4/FileName4_conflict-20130326-030512.ext 25432935 mv c a
任何帮助和建议都将不胜感激。
更新:解决方案
非常抱歉,我没有给出任何清晰的例子来说明我尝试过的方法,我的第一次尝试很混乱。我并不是在寻找完整的脚本,只是寻求一些帮助和指导。无论如何,我花了一天时间研究 shell 脚本(这几乎是我的第一次尝试),并想出了一个适合我的解决方案。您可以在下面找到我的脚本:
#!/bin/bash
# find all files without _conflict-suffix
find ./ -type f ! -name "*_conflict*" -print0 | while read -d $'\0' file
do
# regex to get dir and partial name
if [[ $file =~ ^(.*\/)(.*)(\..*)$ ]] ; then
dir="${BASH_REMATCH[1]}"
# file size in bytes
size=`wc -c < "$file"`
# look for matching files with _conflict-suffix
find "${dir}" -name "${BASH_REMATCH[2]}_conflict-*${BASH_REMATCH[3]}" -print0 | while read -d $'\0' conflict
do
# conflicting filesize in bytes
conSize=`wc -c < "$conflict"`
# check if conflict-file is bigger
if [[ $size -lt $conSize ]] ; then
# It is! Remove, rename, and update variable with new size
rm "${file}"
mv "${conflict}" "${file}"
set size=conSize
else
# It isn't, remove the trash.
rm "${conflict}"
fi
done
fi
done
请查看@NSD 的回答以找到另一种解决方案。
答案1
嗯......有点觉得你被否决了有点不好意思,我有一些东西可以帮助你开始。
我读过规则,似乎你已经准备好了对哪个文件要做什么的描述.....下面的示例脚本使用该描述符来确定要采取什么操作,然后执行该操作(注意 - mv 和 rm 命令已被注释,我使用 echo 进行测试,取消注释它们以获取实际操作)
代码::
Kaizen ~/so_test/test $ cat ztest.sh
## remove header
sed -i '1d' zlst ;
:>ztmp ;
## loop to parse the file entries one by one
while read line
do
echo $line ;
file=`echo $line | tr -s " " | cut -d" " -f2`;
file=`basename $file .ext` ; #3 used to filter a selection for action
echo $file ;
dir=`echo $line | tr -s " " | cut -d" " -f2`;
dir=`basename $dir` ; #3 used to change the directory to where action is to be performed
cd $dir && echo $dir ;
grep -i $file zlst > ztmp ;
axn=`echo $line | tr -s " " | cut -d" " -f4` ;
## case to select the course of axn
case $axn in
mv )
echo `echo $line | tr -s " " | cut -d" " -f4-`;
file=`echo $line | tr -s " " | cut -d" " -f5` ;
old_name=`grep -w "${file}" ztmp | cut -d" " -f2` ;
old_name=`basename $old_name` ;
file=`echo $line | tr -s " " | cut -d" " -f6` ;
new_name=`grep -w "${file}" ztmp | cut -d" " -f2` ;
new_name=`basename $new_name` ;
echo " mv $old_name $new_name ;" ;
#mv $old_name $new_name ;
## break ;;
;;
rm )
#file=`echo $line | tr -s " " | cut -d" " -f4-`;
echo "rm $file" ;
#rm $file ;
## break ;;
;;
* )
:
echo "do nothing " ;
#break ;;
;;
esac
##empty the tmp file
:> ztmp ;
done < zlst ## end the while loop @ EOF.
输出 ::
Kaizen ~/so_test/test $ . ./ztest.sh
a. /path/to/dir1/FileName1.ext 0 rm
FileName1
rm FileName1
b. /path/to/dir1/FileName1_conflict-20130324-231953.ext 21624832 mv b a
FileName1_conflict-20130324-231953
mv b a
mv FileName1_conflict-20130324-231953.ext FileName1_conflict-20130324-231953.ext ;
c. /path/to/dir1/FileName1_conflict-20130326-080529.ext 21624832 rm
FileName1_conflict-20130326-080529
rm FileName1_conflict-20130326-080529
.ext
do nothing
a. /path/to/dir2/FileName2.ext 25432935 -
FileName2
do nothing
b. /path/to/dir2/FileName2_conflict-20130324-092544.ext 0 rm
FileName2_conflict-20130324-092544
rm FileName2_conflict-20130324-092544
c. /path/to/dir2/FileName2_conflict-20130326-212307.ext 25432935 rm
FileName2_conflict-20130326-212307
rm FileName2_conflict-20130326-212307
.ext
do nothing
a. /path/to/dir3/FileName3.ext 0 rm
FileName3
rm FileName3
b. /path/to/dir3/FileName3_conflict-20130324-214501.ext 23422234 mv b a
FileName3_conflict-20130324-214501
mv b a
mv FileName3_conflict-20130324-214501.ext FileName3_conflict-20130324-214501.ext ;
.ext
do nothing
a. /path/to/dir4/FileName4.ext 0 rm
FileName4
rm FileName4
b. /path/to/dir4/FileName4_conflict-20130324-110541.ext 14423 rm
FileName4_conflict-20130324-110541
rm FileName4_conflict-20130324-110541
c. /path/to/dir4/FileName4_conflict-20130326-030512.ext 25432935 mv c a
FileName4_conflict-20130326-030512
mv c a
mv FileName4_conflict-20130326-030512.ext FileName4_conflict-20130326-030512.ext ;
请注意:对于大小检查,我没有将其包含在代码中,while 循环中的一个简单 if 条件就可以了......不过您需要添加它。
希望这可以帮助 !!