Exclui todos os arquivos, exceto os maiores, em vários diretórios

1

Eu tenho vários subdiretórios em /home/usr/ProjZ/programs/ , cada um contendo vários (ou um)% de arquivos.js.

O que eu preciso fazer é excluir todos, menos o maior arquivo .js , se o subdiretório contiver vários arquivos ou não fizer nada se o subdiretório contiver apenas um arquivo .js .

Como posso fazer isso?

    
por user334455 31.07.2014 / 20:28

4 respostas

2

com zsh :

for dir (/home/usr/ProjZ/programs/*(/)) rm -f $dir/*.js(.NOL[2,-1])

Observe que, se houver vários arquivos com o maior tamanho, apenas um será retido. Qual deles será depende da ordem em que aparecem no diretório atual (que geralmente é mais ou menos aleatório).

GNUly (% GNU sed para -z ), o equivalente seria parecido com:

for dir in /home/usr/ProjZ/programs/*; do
  [ -d "$dir" && ! -L "$dir" ] || continue
  find "$dir" -type f -printf '%s:%p
for dir (/home/usr/ProjZ/programs/*(/)) rm -f $dir/*.js(.NOL[2,-1])
' | sort -rzn | sed -z '1d;s/[^:]*://' | xargs -r0 rm -f done
    
por 31.07.2014 / 21:23
0

Não está claro para mim se os arquivos .js estão todos em um único diretório, ou se eles existem em qualquer lugar abaixo desse ponto.

Se você quiser apenas remover todos, exceto os maiores .js de um único diretório, poderá fazer algo assim:

$ ls -S *.js | tail --lines=+2 | xargs rm

Isso não é seguro se os arquivos tiverem caracteres estranhos como espaço em branco.

Se o .js puder existir a qualquer profundidade, eu provavelmente o roteiro.

perl

use File::Find;
find(\&wanted, "/path/to/look/in");
my $biggest_file;
my $biggest_size = 0;
sub wanted {
  if ($_ =~ /\.js$/) {
    my ($size) = (stat $_)[7];
    if ($size > $biggest_size) {
      unlink $biggest_file if defined $biggest_file;
      $biggest_size = $size;
      $biggest_file = $File::Find::name;
    }
  }
}
    
por 31.07.2014 / 21:40
0

Algumas boas respostas, mas eu prefiro mantê-lo simples e fazê-lo em bash . Especialmente se você é um novato.

Veja como farei isso com alguns comentários para ajudar você a acompanhar:

#!/bin/bash

# Loop through all subdirectories
for dir in $(find /home/usr/ProjZ/programs/ -type d)
do

    # Get all .js files in this subdir
    files=$(find $dir -maxdepth 1 -type f -name '*.js')

    # If there's no files in here, just skip this subdir
    if [ -z "$files" ]
    then
        continue
    fi

    # Get deletion candidates (sort by size, remove the biggest, get filenames)
    rm_candidates=$(stat -c "%s %n" ${files} | sort -n | head -n -1 | cut -d" " -f2-)

    # Finally, remove each file
    for file in $rm_candidates
    do
        rm -f $file
    done
done

Espero que isso ajude!

    
por 31.07.2014 / 22:05
0

Esse pequeno script bash será manipulado corretamente quando o arquivo .js puder ter espaços no nome e onde os diretórios possam conter arquivos .js e outras extensões.

#!/bin/bash
find /home/usr/ProjZ/programs/* -type d | while read "x"; do
NUMFILES='ls -1 "$x"/*.js | wc -l'
[[ $NUMFILES -gt 2 ]] && ls -1Sr "$x"/*.js 2>/dev/null | head -n $(($NUMFILES-2)) | xargs -I{} rm -f "{}"
done 2>/dev/null
    
por 31.07.2014 / 22:26