Comando para excluir arquivos temporários que terminam com ~

15

Muitos dias atrás, encontrei este alias útil do bash (conteúdo das minhas ~ / .bash_aliases )

# aliases

# finds temporary files ending with '~' and deletes them
alias rm~='find . -name '*~' -print0 | xargs -0 /bin/rm -f'

Agora tentei usar rm~depois cdde algum diretório contendo 3 arquivos que terminam em~

Eu recebi este erro no terminal e os arquivos não foram excluídos

find: paths must precede expression: 1n.in~
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

Além disso, quando eu tentei rm~partir /home/me, parece não estar fazendo nada. Ou pode levar muito tempo.

Diga-me por que estou recebendo um erro e como corrigi-lo.

Obrigado!

Vinayak Garg
fonte

Respostas:

26

Seu alias do bash não está bem escrito (as aspas simples não são bem usadas). Em vez disso, deve ser:

alias rm~='find . -name "*~" -print0 | xargs -0 /bin/rm -f'

Agora, pessoalmente, eu não gosto de usos inúteis de pipes e xargs, portanto, seu apelido seria melhor escrito como:

alias rm~='find . -name "*~" -type f -exec /bin/rm -fv -- {} +'

A -type fopção para encontrar apenas arquivos (não diretórios, links etc.), a -vopção rmpara ser detalhado (imprime o que está excluindo). O +no final, para que seja findexecutado rmcom todos os arquivos encontrados (gera apenas uma instância de rm, em vez de uma por arquivo).

Agora de man bash:

Para quase todos os propósitos, os aliases são substituídos pelas funções do shell.

Em vez de um apelido, é melhor usar uma função: comente seu apelido no .bash_aliasesarquivo (por exemplo, coloque um #na frente dessa linha) e, no arquivo .bashrc, coloque essa função (em qualquer lugar do arquivo, no final, tudo bem) :

rm~() {
    find . -name "*~" -type f -exec /bin/rm -fv -- {} +
}

Além disso, como a outra resposta menciona, você pode usar o -deletecomando para encontrar. Nesse caso, sua rm~função será:

rm~() {
    find . -name "*~" -type f -printf "Removing file %p\n" -delete
}

De fato, você pode criar uma função interessante que levará um argumento, digamos --dry-run, que apenas produzirá o que será excluído:

rm~() {
    case "$1" in
    "--dry-run")
        find . -name "*~" -type f -printf "[dry-run] Removing file %p\n"
        ;;
    "")
        find . -name "*~" -type f -printf "Removing file %p\n" -delete
        ;;
    *)
        echo "Unsupported option \`$1'. Did you mean --dry-run?"
        ;;
    esac
}

Então use como:

rm~ --dry-run

para mostrar apenas os arquivos que serão excluídos (mas não para excluí-los) e, em seguida,

rm~

quando você está feliz com isso.

Adapte e estenda às suas necessidades!

Nota. Você precisará abrir um novo terminal para que as alterações entrem em vigor.

gniourf_gniourf
fonte
Obrigado! Funciona bem e o funcionamento a seco é extremamente útil.
Vinayak Garg
2
find -type f -name '*~' -delete(arma de escolha, além disso git clean -dfx .)
veja 28/12/12
2
Essa é uma solução tão elegante que eu tive que fazer login apenas para fornecer adereços. +1 para você, meu bom amigo!
CodeChimp
9

*~é expandido pelo shell antes de ser atribuído ao seu alias. A atribuição real é:

alias rm~='find .name some~ file~ 1n.in~ -print0 | xargs -0 /bin/rm -f'

Sugiro usar funções em vez de pseudônimos; elas são muito mais poderosas e fáceis de manusear em relação a aspas.

Enquanto estamos nisso, remova o supérfluo .(o diretório atual é implícito se nenhum parâmetro for fornecido) e pare de abusar, xargspois -deletejá existe uma opção.

rm~() { find -name '*~' -ls -delete; }

A -lsopção é opcional, mas adicioná-la mostrará quais arquivos foram excluídos.

Lekensteyn
fonte
+1 Obrigado! Mas onde eu adiciono essa função?
Vinayak Garg
@VinayakGarg Você também pode adicioná-lo ao seu .bash_aliases, mas eu costumo colocá-lo direto no meu .bashrc.
Lekensteyn