根据大小和命名删除和重命名文件的 Bash 脚本

根据大小和命名删除和重命名文件的 Bash 脚本

我的目录中有多个冲突文件,我正在寻找一种方法,根据文件的名称和大小,根据不同的模式对重复项进行排序、命名和删除。虽然我对 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 条件就可以了......不过您需要添加它。

希望这可以帮助 !!

相关内容