Jak cytować argumenty za pomocą xargs

15

Załóżmy, że chcę usunąć wszystkie pliki w folderze, które są większe niż 1 MB.

$ find . -size +1M | xargs -0 rm

Nie spowoduje to usunięcia plików, które mają spacje w swoich nazwach. Chcę, żeby zacytował wszystkie argumenty, do których wysyła rm. Jeśli finddaje to Some report.docxpowinien on przejść "Some report.docx"do rm.

Jak mogę to zrobić?

Kshitiz Sharma
źródło
1
Powinieneś przeczytać ten mywiki.wooledge.org/UsingFind?highlight=%28xargs%29 przed zrobieniem czegokolwiek xargs. Również, jak sugeruje wiki, nie używaj xargsbez przekazania -print0do find.
Valentin Bajrami,
1
Mówiąc bardziej ogólnie, zobacz Dlaczego mój skrypt powłoki dusi się na białych znakach lub innych znakach specjalnych?
Gilles „SO- przestań być zły”
Użyj, xargs -d$'\n'aby ograniczyć ogranicznik tylko do nowych wierszy (a nie spacji; nie przetwarzałoby to specjalnie cudzysłowów itp. - Sprawdziłem w systemie GNU) - odpowiedź podana w stackoverflow.com/a/33528111/94687
imz - Ivan Zachharyaschev

Odpowiedzi:

13

Proste użycie:

find . -size +1M -delete

Jeśli nalegasz na używanie xargsi rmprzy pomocy find, po prostu dodaj -print0polecenie:

find . -size +1M -print0 | xargs -r0 rm --

Inny sposób:

find . -size +1M -execdir rm -- {} +

Od man find:

-print0
    True; print the full file name on the standard output, followed by a null 
character (instead of the newline character that -print uses). This allows file names 
that contain newlines or other types of white space to be correctly interpreted by 
programs that process the find output. This option corresponds to the -0 option of 
xargs.
αғsнιη
źródło
3
To rozwiązuje problem, ale w rzeczywistości cytowanie argumentów byłoby przydatne w innych przypadkach. Więc czekam na inne odpowiedzi. +1 za proste rozwiązanie.
Kshitiz Sharma,
2
@KshitizSharma Nie, nie chcesz przejść "Some report.docx"do rm, chyba że nazwa pliku zawiera cudzysłowy. To, czego chcesz, to przekazanie Some report.docxniezbawionego rm. Odpowiedź KasiyA (teraz) pokazuje ogólny sposób, aby to zrobić find. [KasiyA: przepraszam za zły ping.]
Gilles „SO- przestań być zły”
@Gilles Correct. W bash generalnie cytuję ciąg, aby przekazać go bez przeszkód. Więc cytując Chodziło mi o to, aby wysłać pliku jako pojedynczy argument do rm zamiast być podzielony na $0i $1itd.
Kshitiz Sharma
W OSX robię to xargs -0zamiast xargs -r0.
Rolf
8

Opcja -0z xargspomocą, że wyjście z rury jest interpretowany jako NUL przedmiotów. W takim przypadku musisz również utworzyć dane wejściowe dla potoku za pomocą find ... -print0.

jimmij
źródło
6

Miałem podobny wymóg i ostatecznie użyłem -Iprzełącznika, aby mieć symbol zastępczy i mogłem go zacytować.

find . -size +1M | xargs -I {} rm "{}"
Dee-See
źródło