Znajdź wszystkie pliki bez bajtów w katalogu i podkatalogach


82

Jak mogę znaleźć wszystkie pliki o rozmiarze zerowym w katalogu i jego podkatalogach?

Ja to zrobiłem:

#!/bin/bash
lns=`vdir -R *.* $dir| awk '{print $8"\t"$5}'`
temp=""
for file in $lns; do
    if test $file = "0"; then
        printf $temp"\t"$file"\n"
    fi
    temp=$file
done

Ale wyniki otrzymuję tylko w bieżącym katalogu, a nie w podkatalogach, a jeśli jakakolwiek nazwa pliku zawiera spację, otrzymuję tylko pierwsze słowo, po którym następuje tab


1
Możesz przeczytać man find.
alk

1
Pytanie również opublikowane na unix i linux - prosimy nie publikować tego samego pytania w wielu miejscach.
glenn jackman

Następnym razem nie będę się powtarzał w ten sposób z powodu problemu w mojej przeglądarce z przepełnieniem stosu, który opublikowałem w superużytkowniku, ale teraz problem został rozwiązany przez wyczyszczenie plików cookie historii i przechwycenie w ie, więc zapytałem ponownie tutaj
Civa

Odpowiedzi:


174

Aby wydrukować nazwy wszystkich plików w $ dir i poniżej o rozmiarze 0:

find "$dir" -size 0

Zwróć uwagę, że nie wszystkie implementacje finddomyślnie będą generować dane wyjściowe, więc może być konieczne wykonanie:

find "$dir" -size 0 -print

Dwie uwagi na temat ostatniej pętli w pytaniu:

Zamiast iterować po każdym innym słowie w ciągu i sprawdzać, czy wartości alternatywne są równe zero, możesz częściowo wyeliminować problem z białymi znakami, wykonując iterację po liniach. na przykład:

printf '1 f1\n0 f 2\n10 f3\n' | while read size path; do
    test "$size" -eq 0 && echo "$path"; done

Zauważ, że to się nie powiedzie w twoim przypadku, jeśli którakolwiek ze ścieżek wyjściowych ls zawiera znaki nowej linii, a to wzmacnia 2 punkty: nie analizuj ls znaki i miej rozsądną politykę nazewnictwa, która nie zezwala na spacje w ścieżkach.

Po drugie, aby wyprowadzić dane z pętli, nie ma potrzeby zapisywania danych wyjściowych w zmiennej tylko do echoniej. Jeśli po prostu pozwolisz pętli zapisać swoje wyjście na stdout, osiągniesz to samo, ale unikniesz przechowywania go.


czy mogę filtrować katalog inny niż * .xml
Civa

2
Jest też wygodna -emptyopcja.
Wesley Baugh

@WesleyBaugh z opcją -empty otrzymujesz również katalogi z zerowymi plikami w środku
Igor Scabini

1
@IgorScabini Jeśli chcesz ograniczyć się do plików, możesz to zrobić za pomocą -type f.
Wesley Baugh,

Śliczny! Prosto i do rzeczy. Człowieku, nie używam tego findpolecenia wystarczająco. Naprawdę muszę się pozbyć strachu przed zrozumieniem tego. Tak przydatne.
racl101

32

Jako dodatek do powyższych odpowiedzi:

Jeśli chcesz usunąć te pliki

find $dir -size 0 -type f -delete

1
nie jest konieczne ciągłe usuwanie całego pliku o rozmiarze 0.
Raghvendra

następnie jak usunąć plik w folderze o rozmiarze 0
Raghvendra,

-exec /bin/rm {} \;lub -exec /bin/rm {} +będzie działać również na findimplementacjach innych niż GNU , które nie obsługują niestandardowego rozszerzenia-delete
Gert van den Berg

8

Nie, nie musisz zawracać sobie głowy grepem.

find $dir -size 0 ! -name "*.xml"

3

Przetestowano Bash 4+ - to poprawny sposób wyszukiwania rozmiaru 0:

find /path/to/dir -size 0 -type f -name "*.xml"

Wyszukaj wiele rozszerzeń plików o rozmiarze 0:

find /path/to/dir -size 0 -type f \( -iname \*.css -o -iname \*.js \)

Uwaga: jeśli usuniesz \ (... \), wynikiem będą wszystkie pliki, które spełniają to wymaganie, a zatem rozmiar 0 zostanie zignorowany.


-inamenie jest przenośny do niektórych implementacji innych niż GNU. findZobacz tutaj listę standardowych opcji
Gert van den Berg
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.