Como excluir arquivos filtrados por awk

3

Eu tenho os seguintes arquivos em um diretório:

-rw-r--r-- 1 smsc sys  46 Apr 22 12:09 bills.50.1.3G.MO.X.20120422120453.Z
-rw-r--r-- 1 smsc sys  28 Apr 22 12:15 bills.50.1.3G.MO.X.20120422120953.Z
-rw-r--r-- 1 smsc sys  46 Apr 22 12:20 bills.50.1.3G.MO.X.20120422121453.Z
-rw-r--r-- 1 smsc sys  46 Apr 22 12:25 bills.50.1.3G.MO.X.20120422121953.Z

Onde a quinta coluna é o tamanho do arquivo. Desejo excluir todos os arquivos cujo tamanho é 46. Para filtrar esses arquivos, usei o seguinte comando:

ls -ltr | awk '$5 ~ /46/ {print $0}'

O que funciona bem. Mas agora eu quero excluir todos os arquivos que foram filtrados, então adiciono o seguinte ao comando acima:

ls -ltr | awk '$5 ~ /46/ {print $0}' | xargs rm

No entanto, isso me dá o seguinte erro:

rm: invalid option -- w

Parece que eu tenho que usar find over ls , então vou pegar a saída no formato abaixo:

./bills.50.1.3G.MO.X.20120421050453.Z
./bills.50.1.3G.MO.X.20120421154953.Z
./bills.50.1.3G.MO.X.20120419133452.Z

Mas não tenho como filtrar os arquivos por seus parâmetros. Como esta tarefa poderia ser feita?

    
por Eugene S 22.04.2012 / 11:42

3 respostas

10

Você tem dois bugs:

  1. Você está comparando com um tamanho que contém 46 ; você quer que seja igual a 46.

  2. Você está imprimindo a linha inteira, quando deseja apenas o nome do arquivo.

E um problema adicional: qual é o sentido de -ltr classificar a saída ls quando você não está usando a ordem de classificação?

Você quer fazer algo como

ls -l | awk '$5 == "46" {print $9}' | xargs rm

Exceto que você não quer fazer isso, porque embora possa estar seguro no momento, a análise da saída ls não é confiável. Use uma ferramenta apropriada, como

find . -maxdepth 1 -size 46c -delete # requires GNU find

(Fazer isso portably é mais chato, já que POSIX find não tem -maxdepth ou -size que opera em unidades diferentes de blocos. Melhor escrever um script em Perl / Python / Ruby / etc. que pode usar uma varredura de diretório apropriada que não terá problemas com caracteres especiais em nomes de arquivos.

    
por 22.04.2012 / 11:47
2

Em zsh, para remover todos os arquivos de tamanho 26 no diretório atual (primeira linha) ou o diretório atual e seus subdiretórios (segunda linha), use o L qualificador glob :

rm *(L26)
rm **/*(L26)

Com o GNU ou FreeBSD / NetBSD / OSX, ache:

find . -name . -o -type d -prune -o -type f -size 26c -exec rm {} +
find . -type f -size 26c -exec rm {} +

Portável:

find . -name . -o -type d -prune -o -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
find . -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
    
por 23.04.2012 / 02:17
0

find é a melhor opção aqui. você pode usar stat para encontrar o tamanho do arquivo sem usar ls

for file in *; do
  (( $(stat -c %s "$file") == 46 )) && rm "$file"
done
    
por 22.04.2012 / 14:24

Tags