Chcę usunąć wszystkie pliki zawierające ciąg foo. Jak mogę to zrobić za pomocą bash w systemie Linux?
foo(np. myfoo.jpg), Czy pliki zawierające sekwencję bajtów foo(które mogą obejmować pliki binarne, które akurat zawierają sekwencję bajtów)?
Chcę usunąć wszystkie pliki zawierające ciąg foo. Jak mogę to zrobić za pomocą bash w systemie Linux?
foo(np. myfoo.jpg), Czy pliki zawierające sekwencję bajtów foo(które mogą obejmować pliki binarne, które akurat zawierają sekwencję bajtów)?
Odpowiedzi:
Oto bezpieczny sposób:
grep -lrIZ foo . | xargs -0 rm -f --
-l drukuje nazwy plików pasujących do wzorca wyszukiwania.-rwykonuje rekurencyjne wyszukiwanie wzorca foow podanym katalogu .. Jeśli to nie zadziała, spróbuj -R.-I(kapitał i) powoduje pomijanie plików binarnych, takich jak pliki PDF.-Z zapewnia, że nazwy plików są zerowane (tj. nul-), tak aby nazwa zawierająca białe znaki nie była interpretowana w niewłaściwy sposób (tzn. jako wiele nazw zamiast jednej).xargs -0podaje nazwy plików od grepdo rm -f, oddzielając słowa przez zero (nul) bajtów (pamiętaj -Zopcję od grep).--jest często zapominany, ale bardzo ważne jest zaznaczenie końca opcji i umożliwienie usunięcia plików, których nazwy zaczynają się -.Jeśli chcesz zobaczyć, które pliki mają zostać usunięte, po prostu usuń | xargs -0 rm -f --część i pozostaw Zopcję grep.
Inny użytkownik zasugerował coś takiego, czego nie należy uruchamiać, ponieważ jest to niebezpieczne:
files=`grep foo * | cut -d: -f1`
rm -f $files # unsafe, do not run it!
Jeśli mam pliki ImportantStuff, których nie chcę usuwać i które obsolete ImportantStuffzawierają foo, tracę ImportantStuff(i nie obsolete ImportantStuff !) Po uruchomieniu tego polecenia, ponieważ $filesrozpada się na spacje podczas interpretacji. W ten sposób umieszczanie listy nazw plików w zmiennej powłoki skalarnej jest niebezpieczne.
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;
Rekurencyjnie wyszukuje pliki zawierające foo . Drugi -execjest uruchamiany tylko wtedy, gdy pierwszy execzakończy się pomyślnie, tzn. Jeśli greppasuje. Dryrun i usuń, echojeśli wyjście wydaje się prawidłowe.
Lub alternatywnie
$ find -type f -exec grep -q "foo" {} \; -print
i
$ find -type f -exec grep -q "foo" {} \; -delete
jak sugeruje Lekensteyn.
find -type f -exec grep -q 'foo' {} \; -delete(cytaty {}są zbędne, findmożna także usuwać pliki). Uwaga: grepakceptuje wyrażenie regularne. Jeśli chcesz wyszukać foo.bar, albo uniknij tego, albo przekaż -Fopcję traktowania wzorca jako dosłownego.
-exec echo rm "{}" \;a nie -delete?
-delete. Łatwiej jest zademonstrować z drugim -execi rozbrzmiewającym echem.
-print(lub -lsdla większej szczegółowości) niż -exec echo rm "{}" \'. Nie potrzeba zewnętrznych narzędzi.
Zrobiłbym to, co mówi Adrian,
Ale dodam granice słów wokół foo, aby przypadkowo nie usunąć plików zawierających „jedzenie” (chyba że usuwa wszystko, co zawiera jedzenie).
$ find -type f -exec grep -q "\<foo\>" {} \; -delete
acutally, przekierowałem dane wyjściowe przed usunięciem, aby móc przejrzeć przed usunięciem:
$ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete