Jaka jest poprawna składnia find -exec

10

Chciałem usunąć pliki o rozmiarze większym niż 2 MB w określonym folderze. Więc pobiegłem:

find . -size +2M

I mam listę dwóch plików

./a/b/c/file1

./a/f/g/file2

Więc uruchamiam:

find . -size +2M -exec rm ;

i dostaję komunikat o błędzie Find: missing argument to -exec

Sprawdzam składnię na stronie podręcznika i mówi: -exec command ;

Zamiast tego próbuję

find . -size +2M -exec rm {} +

I to działa. Rozumiem, że {} sprawia, że ​​wykonuje polecenie jak rm file1 file2zamiast rm file1; rm file2;.

Dlaczego więc pierwszy nie zadziałał?

ODPOWIEDŹ:

Chyba musiałem kilka razy RTFM, aby w końcu zrozumieć, co mówi. Mimo że pierwszy przykład nie pokazuje {}, nawiasy klamrowe są wymagane we wszystkich przypadkach. A następnie dodaj \; lub + w zależności od żądanej metody. Nie czytaj tylko nagłówka. Przeczytaj także opis. Rozumiem.

Safado
źródło

Odpowiedzi:

16

Możesz użyć dowolnej formy:

find . -size +2M -exec rm {} +

find . -size +2M -exec rm {} \;

Średnik należy uciec!

Khaled
źródło
10
-exec rm {} \;

możesz użyć .. man find

-exec command ;
              Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to the  command  until
              an  argument  consisting of `;' is encountered.  The string `{}' is replaced by the current file name being processed everywhere
              it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.  Both of  these
              constructions  might  need  to  be escaped (with a `\') or quoted to protect them from expansion by the shell.  See the EXAMPLES
              section for examples of the use of the -exec option.  The specified command is run once for each matched file.  The  command  is
              executed  in  the  starting directory.   There are unavoidable security problems surrounding use of the -exec action; you should
              use the -execdir option instead.

       -exec command {} +
              This variant of the -exec action runs the specified command on the selected files, but the command line is  built  by  appending
              each  selected file name at the end; the total number of invocations of the command will be much less than the number of matched
              files.  The command line is built in much the same way that xargs builds its command  lines.   Only  one  instance  of  `{}'  is
              allowed within the command.  The command is executed in the starting directory.
dSoultanis
źródło
1
Ach, okej Chyba musiałem kilka razy RTFM, aby w końcu zrozumieć, co mówi. Mimo że pierwszy przykład nie pokazuje {}, nawiasy klamrowe są wymagane we wszystkich przypadkach. A następnie dodaj \; lub + w zależności od żądanej metody. Rozumiem.
Safado
2

Ze względu na wydajność zwykle lepiej jest używać xargs:

$ find /path/to/files -size +2M -print0 | xargs -0 rm
EEAA
źródło
1
Nie całkiem. Jak mówi wpis Guide na wiki Grega: + (zamiast;) na końcu akcji -exec mówi find, aby użył wewnętrznej funkcji podobnej do xargs, która powoduje, że polecenie rm jest wywoływane tylko raz dla każdej części plików, zamiast raz na plik.
adapttr
Ahh, ciekawe. Od lat używam find + xargs i nigdy nie wiedziałem o operatorze +. Dzięki za zwrócenie na to uwagi!
EEAA
Z całego serca mogę polecić wiki Grega; ten człowiek wie więcej o bash i zestawie narzędzi GNU, niż mogłem się kiedykolwiek nauczyć; można śmiało powiedzieć, że nauczyłem się więcej o używaniu bash, odkąd zacząłem go czytać niż przez wszystkie poprzednie lata.
adapttr
2
Kim jest Greg i gdzie mogę znaleźć jego wiki?
Safado
@Safado Myślę, że to ten: mywiki.wooledge.org
Enrico Stahn
0

Nie użyłbym do tego -exec. find może również usunąć same pliki:

find . -size +2M -delete

(prawdopodobnie jest to GNUism, nie wiem, czy znajdziesz to w znalezieniu innym niż GNU)

gulasz
źródło
Czy kryje się za tym jakiś powód, czy jest to po prostu osobiste preferencje?
Safado
find po prostu wywołuje sam unlink (2) i nie musi wydzielać nowych procesów, aby wykonać usuwanie. Byłoby to znacznie bardziej wydajne. Jest również znacznie bardziej czytelny.
gulasz
0

Jak udokumentowano, -exec wymaga {} jako symbolu zastępczego dla wyniku find.

Ostateczny przewodnik dotyczący używania narzędzi bash i GNU znajduje się tutaj

Jak widać, wyraźnie pokazuje drugie polecenie użyte jako przykład.

adapttr
źródło