apaga todos os arquivos que terminam com determinada string

2

Eu tenho um diretório contendo cerca de 15 mil imagens, com um número x de sequências

scene1_000000.png
scene1_000001.png
scene1_000002.png
scene1_000003.png
scene1_000004.png
scene1_000005.png
scene1_000006.png
scene1_000007.png
scene1_000008.png
       .
       .
       .
       .
scene2_000300.png
scene2_000000.png
scene2_000001.png
scene2_000002.png
scene2_000003.png
scene2_000004.png
scene2_000005.png
scene2_000006.png
scene2_000007.png
scene2_000008.png
       .
       .
       .
       .
scene2_000300.png
       .
       .
       .
       .
scene50_000000.png
scene50_000001.png
scene50_000002.png
scene50_000003.png
scene50_000004.png
scene50_000005.png
scene50_000006.png
scene50_000007.png
scene50_000008.png
       .
       .
       .
       .
scene50_000300.png

Eu quero manter de cada seqüência as primeiras 150 seqüências e deletar o resto. Então eu vou ter para cada cena, as seqüências de 000000 a 000150

    
por Mostafa Hussein 10.07.2018 / 18:20

4 respostas

4

Com uma versão recente do bash, você pode usar a expansão de chaves para isso:

rm scene*_{000151..000300}.png

A expansão de chaves do Bash lida com os 0s principais:

$ echo {000000..000005}.png
000000.png 000001.png 000002.png 000003.png 000004.png 000005.png

Então você pode usar {000151..000300} para gerar a lista de arquivos que você precisa.

    
por 10.07.2018 / 18:23
4

Usando find :

find . -maxdepth 1 -type f \
         -name 'scene*.png' \
       ! -name '*_0000[0-9][0-9].png' \
       ! -name '*_0001[0-4][0-9].png' \
       ! -name '*_000150.png' -print -delete

Isso localizaria todos os arquivos que você deseja excluir no diretório atual (apenas).

Os vários -name sinalizadores fazem o seguinte:

  1. Selecione apenas as que correspondem a scene*.png .
  2. Filtre os nomes de arquivo (remover da seleção) que estão no intervalo 000000.png a 000099.png .
  3. Filtre os nomes de arquivos que estão no intervalo 000100.png a 000149.png .
  4. Filtre nomes de arquivos que terminam em 000150.png .

... exclua o arquivo, se ainda for considerado. Os testes de segundo, terceiro e quarto -name são negados para impedir find de excluir esses arquivos (esses são os que gostaríamos de manter).

Os nomes dos arquivos excluídos também serão impressos antes que a exclusão real ocorra.

Sugiro que você execute isso com -delete removido primeiro.

    
por 10.07.2018 / 18:42
2

Em zsh, a construção <m-n> corresponde a cadeias que são números entre me n. Ambos são opcionais. Assim:

rm scene<->_<151->.png

(você também pode iniciar o caractere curinga com scene*_ , mas <-> seria uma proteção contra * correspondendo a algo não intencional se houver arquivos nomeados de acordo com um padrão diferente)

    
por 10.07.2018 / 22:43
0

Talvez um pequeno roteiro:

echo '#!/bin/bash
# Test argument
if [ $# = 1 ]; then
  if [ -d $1 ]; then
    cd $1
  else
    echo "$1 is not a directory" >&2
    exit 1
  fi
fi

declare f      # filname
declare -i fc  # file counter
declare -i fcs # file conter for a scene
declare sn     # scene number
declare csn    # current scene number
declare -i dfc # delete file counter
declare -i pfc # preserve file counter

# Open logfiles
exec file-delete>>&3
exec file-preserve>>&4

for f in *; do
  ((fc++))
  sn=${f#scene}
  sn=${sn%_*}
  if [ "$sn" = "$csn" ]; then
    ((fcs++))
  else
    # New number scene
    fcs=1   
    csn=$sn
    dfc=0
    pfc=0
    echo
  fi
  if ((fcs > 150));then
    # Candidate for deleting
    echo "$f" >>&3
    ((dfc++))
  else
    # Preserve file
    echo "$f" >>&4
    ((pfc++))
  fi
  # Display in console
  echo -en "\r scene $csn preserve:$pfc delete:$dfc"
done
echo

# Closing logfile
exec 3>&-
exec 4>&-

echo "Files scaned : $fc"
wc -l file-delete
wc -l file-preserve
' > ~/scanfile

Para executá-lo:

bash ~/scanfile [<pathdir>]

Se for omitido, ele funcionará no diretório atual.

Ele não exclui nada, ele grava dois arquivos no diretório varrido (exclusão de arquivos e preservação de arquivos).

Após a verificação, os arquivos a serem excluídos podem ser movidos com:

[cd <pathdir>]
mkdir tmp
while read; do mv -v $REPLY tmp; done < file-delete

Se o resultado for bom, então

rm -rf tmp
rm file-delete file-preserve
    
por 11.07.2018 / 02:34

Tags