Como posso remover apenas os arquivos graváveis em um diretório, sem nenhum prompt?

3

Eu quero excluir apenas os arquivos graváveis em um diretório. Se eu fizer

rm *

ele remove todos os arquivos graváveis (até aí tudo bem), mas recebo uma solicitação para cada arquivo não gravável. Eu não quero um prompt, eu só quero deixar os arquivos não graváveis sozinho.

A resposta não é 'rm -f', porque isso removerá os arquivos não graváveis.

Então, existe um comando simples para remover apenas os arquivos graváveis, sem receber nenhum aviso?

    
por Chad 10.03.2016 / 21:09

3 respostas

2

Eu não acho que rm faça isso sozinho, não há sinalização óbvia nas opções.

Você pode usar uma mistura de find e rm para alcançá-lo.

find -maxdepth 1 -type f -writable -exec rm {} +

Por exemplo,

tony@trinity:~/temp$ ls -l
total 0
tony@trinity:~/temp$ touch bob
tony@trinity:~/temp$ touch bill
tony@trinity:~/temp$ touch fred
tony@trinity:~/temp$ chmod 400 fred
tony@trinity:~/temp$ ls -l
total 0
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 bill
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 bob
-r-------- 1 tony tony 0 Mar 10 20:19 fred
tony@trinity:~/temp$ mkdir test
tony@trinity:~/temp$ cd test
tony@trinity:~/temp/test$ touch chris
tony@trinity:~/temp/test$ cd ..
tony@trinity:~/temp$ ls -lR
.:
total 4
-rw-r--r-- 1 tony tony    0 Mar 10 20:19 bill
-rw-r--r-- 1 tony tony    0 Mar 10 20:19 bob
-r-------- 1 tony tony    0 Mar 10 20:19 fred
drwxr-xr-x 2 tony tony 4096 Mar 10 20:19 test

./test:
total 0
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 chris
tony@trinity:~/temp$ find -maxdepth 1 -type f -writable -exec rm {} +
tony@trinity:~/temp$ ls -lR
.:
total 4
-r-------- 1 tony tony    0 Mar 10 20:19 fred
drwxr-xr-x 2 tony tony 4096 Mar 10 20:19 test

./test:
total 0
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 chris

Isso não se comportará da mesma forma que rm -r , então você precisará repensá-lo se quiser descer em subdiretórios e, conforme escrito, ele não removerá os diretórios.

Como @Giles sugere, você também pode usar a ação -delete para fazer todo o trabalho dentro do find , por exemplo,

$ ls -lR
.:
total 4
-rw-r--r-- 1 tony tony    0 Mar 10 23:16 bill
-rw-r--r-- 1 tony tony    0 Mar 10 23:16 bob
-r-------- 1 tony tony    0 Mar 10 20:19 fred
drwxr-xr-x 2 tony tony 4096 Mar 10 20:19 test

./test:
total 0
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 chris
tony@trinity:~/temp$ find -maxdepth 1 -type f -writable -delete
tony@trinity:~/temp$ ls -lR
.:
total 4
-r-------- 1 tony tony    0 Mar 10 20:19 fred
drwxr-xr-x 2 tony tony 4096 Mar 10 20:19 test

./test:
total 0
-rw-r--r-- 1 tony tony 0 Mar 10 20:19 chris
    
por 10.03.2016 / 21:18
1
for f in *; do [ ! -w "$f" ] || rm -- "$f"; done

Ou com && em vez de || :

[ -w "$f" ] && rm -- "$f"

(Eu prefiro || , já que uso muito set -e e uma cláusula && nua e sem sucesso causará uma saída nesse modo)

    
por 10.03.2016 / 21:17
0

com zsh :

rm -- *(@,^/e:'[ -w $REPLY ]':)

Ou seja, remova links simbólicos e não diretórios ( rm não os removeria de qualquer maneira, portanto, poderíamos também excluí-los) para os quais você tem acesso de gravação. Observe que o qualificador w glob não pode ser usado aqui, pois só verifica se o arquivo é gravável pelo seu proprietário (que pode não ser você).

    
por 11.03.2016 / 11:19