Jak w systemie Linux mogę znaleźć wszystkie pliki zawierające ciąg i je usunąć?


17

Chcę usunąć wszystkie pliki zawierające ciąg foo. Jak mogę to zrobić za pomocą bash w systemie Linux?


ten ciąg to nazwa pliku?
rɑːdʒɑ

3
Wyjaśnij: czy chcesz usunąć pliki, których nazwa zawiera 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)?
hammar

Odpowiedzi:


33

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.


17
$ 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.


4
... które można skrócić do: 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.
Lekensteyn,

jakiś powód do korzystania, -exec echo rm "{}" \;a nie -delete?
vartec

1
@vartec Nie, skorzystałbym -delete. Łatwiej jest zademonstrować z drugim -execi rozbrzmiewającym echem.
Adrian Frühwirth

1
Łatwiej jest pisać -print(lub -lsdla większej szczegółowości) niż -exec echo rm "{}" \'. Nie potrzeba zewnętrznych narzędzi.
Lekensteyn,

1
jeśli używasz rm {}, użyj rm - {}, aby żadne znaki specjalne w samej nazwie pliku nie były interpolowane. Na przykład dotknij „-rf /” w dowolnym katalogu, w którym masz uprawnienia do zapisu ...
atk

1

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

Jak tylko będziesz mógł dodawać komentarze, powinieneś zamieścić takie rzeczy jako komentarze.
FSMaxB 21.04.13

tak, najpierw próbowałem, ale potem zdałem sobie sprawę, że nie mogę jeszcze dodawać komentarzy.
Petter H
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.