Script Bash para remover e renomear arquivos com base no tamanho e na nomenclatura

0

Tenho diretórios com vários arquivos conflitantes e estou procurando uma maneira de classificar, nomear e excluir duplicatas com base em um padrão distinto com base no nome e no tamanho do arquivo. Embora meu conhecimento de script bash seja muito limitado, estou procurando por qualquer orientação disponível sobre como criar isso.

  • As duplicatas podem ser distintas por nomes de arquivos e tamanho do arquivo
  • Se houver uma duplicata, o nome do arquivo terminará com _conflict-yyyymmdd-hhmmss.ext
  • Há sempre uma versão não-redefinida do arquivo, mas isso pode estar corrompido
  • O arquivo com o maior tamanho é sempre o correto
  • Vários arquivos podem ter o mesmo tamanho, neste caso, a remoção de duplicatas e renomeação do arquivo é a mais desejável
  • O endfile deve sempre ser não-redefinido

Veja um exemplo de possíveis cenários:

   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

Qualquer ajuda e sugestões com isso seriam muito apreciadas.

Atualização: solução

Sinto muito por não dar exemplos claros do que eu tentei, minhas primeiras tentativas foram uma bagunça. Eu não estava procurando por um roteiro completo, apenas alguns ajudam uma orientação. De qualquer forma, passei o dia examinando os scripts de shell (essa é praticamente a minha primeira tentativa) e descobri uma solução que funciona para mim. Você pode encontrar meu script abaixo:

#!/bin/bash

# find all files without _conflict-suffix
find ./ -type f ! -name "*_conflict*" -print0 | while read -d $'
   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
' 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 $'
#!/bin/bash

# find all files without _conflict-suffix
find ./ -type f ! -name "*_conflict*" -print0 | while read -d $'%pre%' 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 $'%pre%' 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
' 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

Veja a resposta da @ NSD para outra solução.

    
por Simon Kjellberg 16.06.2013 / 15:47

1 resposta

0

hmm .... meio que me senti um pouco mal por ter sido votado, eu tenho algo para você começar.

Eu li as regras e parece que você já tem uma descrição pronta sobre o que deve ser feito para qual arquivo ..... o script de exemplo a seguir usa esse descritor para determinar que ação deve ser executada e, em seguida, executar isso - os comandos mv e rm são comentados, eu estava usando echo para testar, descomente-os para obter a ação real)

código ::

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.

saída ::

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 ;

Por favor, note : para a verificação de tamanho, eu não incluí isso no código, uma simples condição se no loop while vai fazer .... você precisará adicionar isso embora.

espero que isso ajude !!

    
por 16.06.2013 / 17:43

Tags