ls | grep | rm - Jak sformatować to polecenie?

11

Próbuję usunąć kilka plików z określonego katalogu (w systemie Mac OS X za pomocą terminala)

ls | grep \([1-9]\) | xargs rm

powinien załatwić sprawę, ale tak nie jest. Próbuję usunąć dowolny plik z pojedynczą cyfrą w nawiasach w nazwie pliku (duplikaty pobrane z Internetu), ale w końcu robi coś takiego:

> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory

ponieważ nie interpretuje poprawnej przestrzeni. Powinien usunąć „520syllabus2010 (3) .pdf”

Jak to zrobić w odpowiedni sposób?

Dzięki, Jeff

Jeff
źródło
1
Twoja przykładowa nazwa pliku nie zawiera literału #.
Benjamin Bannier
1
@honk: On nie szuka literału #.
Ignacio Vazquez-Abrams
1
Z powodu rozszerzenia przez powłokę, to nie będzie działać zgodnie z oczekiwaniami, jeśli cwd ma plik o nazwie np (3). Najlepiej cytować argumenty, aby powłoka ich nie dotyczyła.
Ignacio Vazquez-Abrams
1
Problem uderza separator en.wikipedia.org/wiki/Xargs#The_separator_problem
Ole Tange

Odpowiedzi:

19

Krótka wersja:

rm *\([1-9]\)*

Nie podłączaj lsdo rur xargs. Zamiast rury find ... -print0do xargs -0, w celu uniknięcia takich problemów.

find . -maxdepth 1 -name '*([1-9])*' -print0 | xargs -0 rm

... które można zapisać jako:

find . -maxdepth 1 -name '*([1-9])*' -exec rm {} \;

i:

find . -maxdepth 1 -name '*([1-9])*' -delete

który można dodatkowo skrócić rmza pomocą symbolu wieloznacznego.


Normalnie, lsi findoddzielne nazwy plików ze znakami nowej linii, ale xargsdzieli swoje wejście od nowego wiersza lub przestrzeni, w wyniku zachowań widać.

Możliwe jest xargspodzielenie tylko według nowego wiersza, ale pliki mogą mieć także nowe wiersze w swoich nazwach. W rzeczywistości w Linuksie i BSD jedynym niedozwolonym znakiem jest bajt „zerowy” lub zerowy - więc należy go używać w takich przypadkach.

W powyższym przykładzie 2 -print0mówi findo oddzieleniu nazw plików bajtem zerowym; to samo dla xargs -0. (Kilka innych narzędzi ma również podobne opcje, takie jak sort -zlub grep -zZ.)

„Wersja skrócona” wykorzystuje prosty znak wieloznaczny powłoki („wzorzec” w bashinstrukcji - patrz sekcja „Rozszerzenie nazwy ścieżki”).

użytkownik1686
źródło
1
I dla bezpieczeństwa, lepiej jest używać, *" "\\([1-9]\\).*aby usuwane były tylko pliki ze spacją przed liczbą paren'd przed (a, żeby być sprawiedliwym) okresem.
Ignacio Vazquez-Abrams
Niezbyt dobrze znam tę składnię, ale na podstawie opinii głosujących spróbowałem i co wiesz ... działało! Dzięki!
Jeff
1
+1. -print0 jest niezbędny do poprawnego połączenia z xargs.
Chris W. Rea