Polecenie usuwania plików tymczasowych kończących się na ~

15

Wiele dni temu znalazłem ten użyteczny alias bash (zawartość moich ~ / .bash_aliases )

# aliases

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

Teraz próbowałem użyć rm~after cddo jakiegoś katalogu zawierającego 3 pliki kończące się na~

Mam ten błąd w terminalu i pliki nie zostały usunięte

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

Także wtedy, gdy próbowałem rm~z /home/me, wydaje się, że nic nie robi. Lub może to zająć dużo czasu.

Powiedz mi, dlaczego otrzymuję błąd i jak go naprawić.

Dzięki!

Vinayak Garg
źródło

Odpowiedzi:

26

Twój alias bash nie jest dobrze napisany (pojedyncze cudzysłowy nie są dobrze używane). Zamiast tego powinno być:

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

Teraz osobiście nie lubię bezużytecznych zastosowań potoków xargs, więc Twój alias lepiej byłoby napisać jako:

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

-type fOpcja, tak aby znaleźć tylko pliki (nie katalogi, linki, itp), The -vopcję rm, tak aby być rozwlekły (drukuje się, co to za kasowanie). Na +końcu, więc finddziała rmze wszystkimi znalezionymi plikami (spawnuje tylko jedną instancję rm, zamiast jednej na plik).

Teraz z man bash:

W prawie każdym celu aliasy są zastępowane przez funkcje powłoki.

Zamiast aliasu lepiej jest użyć funkcji: skomentuj swój alias w .bash_aliasespliku (tj. Umieść #przed tym wierszem), a w pliku .bashrcumieść tę funkcję (w dowolnym miejscu pliku, na końcu jest w porządku) :

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

Ponadto, jak wspomniano w innej odpowiedzi, możesz użyć -deletepolecenia, aby znaleźć. W takim przypadku Twoją rm~funkcją będzie:

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

W rzeczywistości możesz stworzyć fajną funkcję, która weźmie argument, powiedzmy --dry-run, który wyświetli tylko to, co usunie:

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
}

Następnie użyj jako:

rm~ --dry-run

wyświetlać tylko pliki, które zostaną usunięte (ale ich nie usuwać), a następnie

rm~

kiedy jesteś z tego zadowolony.

Dostosuj się i rozszerz do swoich potrzeb!

Uwaga. Będziesz musiał otworzyć nowy terminal, aby zmiany odniosły skutek.

gniourf_gniourf
źródło
Dzięki! Działa ładnie, a suchy bieg jest niezwykle pomocny.
Vinayak Garg
2
find -type f -name '*~' -delete(poza tym broń z wyboru git clean -dfx .)
patrz
2
To takie eleganckie rozwiązanie, musiałem się zalogować, żeby dać ci rekwizyty. +1 dla ciebie, mój dobry człowieku!
CodeChimp,
9

*~zostanie rozszerzony przez powłokę, zanim zostanie przypisana do twojego aliasu. Rzeczywiste zadanie to:

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

Sugeruję używanie funkcji zamiast aliasów, są one znacznie potężniejsze i łatwiejsze w obsłudze w odniesieniu do cudzysłowów.

W tym momencie usuń zbędne .(bieżący katalog jest domyślny, jeśli nie podano żadnych parametrów) i przestań nadużywać, xargsponieważ -deleteopcja już istnieje.

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

-lsOpcja nie jest obowiązkowe, ale dodanie go pokaże które pliki zostały usunięte.

Lekensteyn
źródło
+1 dzięki! Ale gdzie mam dodać tę funkcję?
Vinayak Garg
@VayayakGarg Możesz również dodać to do swojego .bash_aliases, ale zwykle umieszczam je prosto w moim .bashrc.
Lekensteyn