2012-01-19 17 views
5

W jaki sposób jeden test na istnienie plików w katalogu przy użyciu bash?sh: Test na istnienie plików

if ... ; then 
    echo 'Found some!' 
fi 

Żeby było jasne, nie chcę, aby przetestować dla istnienia konkretnego pliku. Chciałbym przetestować, czy określony katalog zawiera dowolne pliki.


poszedłem z:

(
    shopt -s dotglob nullglob 
    existing_files=(./*) 
    if [[ ${#existing_files[@]} -gt 0 ]] ; then 
     some_command "${existing_files[@]}" 
    fi 
) 

Korzystanie tablica unika warunków wyścigu z lektury listy plików dwukrotnie.

+0

Co jeśli katalog zawiera podkatalogi, ale nie zwykłe pliki? –

+0

@Keith Thompson, Nie nastąpi. – ikegami

+0

możliwy duplikat [Sprawdzanie, czy katalog zawiera pliki] (http://stackoverflow.com/questions/91368/checking-if-a-directory-contains-files) –

Odpowiedz

7

Zazwyczaj używam tylko taniego ls -A, aby sprawdzić, czy t oto odpowiedź.

Pseudo-może-poprawna składni-przykład-ahoj:

if [[ $(ls -A my_directory_path_variable) ]] then.... 

edycja, to będzie działać:

myDir=(./*) if [ ${#myDir[@]} -gt 1 ]; then echo "there's something down here"; fi

+0

Ta odpowiedź powinna zadziałać, nawet jeśli jest nieco hackish. Zamierzam zaatakować wszystkie rozwiązania sh/bash. –

+0

Czuje się nieco zakręcony, ale rzeczywiście działa. Nie mogę się doczekać, aby zobaczyć, co wymyślisz :) – ikegami

+1

myDir = (./*) jeśli [$ {# mójDir [@]} -gt 1]; następnie echo "coś tu jest na dole"; fi ... proszę bardzo. podłącz i graj. –

9

Od strony man:

-f file 
      True if file exists and is a regular file. 

Więc:

if [ -f someFileName ]; then echo 'Found some!'; fi 

Edycja: Widzę, że już dostał odpowiedź, ale pod względem kompletności, można skorzystać z informacji w Checking from shell script if a directory contains files - i stracić opcja dotglob, jeśli chcesz ignorować ukryte pliki.

+0

To testuje istnienie określonego pliku. Chciałbym przetestować istnienie jakiegokolwiek pliku. – ikegami

+0

Ah, źle mnie zrozumiałem. OK, czy potrzebujesz złapać ukryte (to znaczy .xyz) pliki? –

+0

Nie, ignorowanie ukrytych plików jest w porządku. – ikegami

1
#!/bin/bash 

if [ -e $1 ]; then 
     echo "File exists" 
else 
     echo "Files does not exist" 
fi 
+0

To testuje istnienie określonego pliku. Chciałbym przetestować istnienie dowolnego pliku w określonym katalogu. – ikegami

3

Można użyć ls w instrukcji if zatem :

if [[ "$(ls -a1 | egrep -v '^\.$|^\.\.$')" = "" ]] ; then echo empty ; fi 

lub dzięki Ikegami,

if [[ "$(ls -A)" = "" ]] ; then echo empty ; fi 

lub, jeszcze krócej:

if [[ -z "$(ls -A)" ]] ; then echo empty ; fi 

Są w zasadzie Lista wszystkich plików w bieżącym katalogu (w tym ukrytych), które nie są ani . ani ...

Jeśli ta lista jest pusta, oznacza to, że katalog jest pusty.

Jeśli chcesz dyskontować ukryte pliki, można uprościć do:

if [[ "$(ls)" = "" ]] ; then echo empty ; fi 

bash rozwiązanie -tylko (bez powołując programy zewnętrzne takie jak ls lub egrep) może odbywać się w sposób następujący:

emp=Y; for i in *; do if [[ $i != "*" ]]; then emp=N; break; fi; done; echo $emp 

to nie najładniejszy kod w świecie, po prostu ustawia emp do Y, a następnie, dla każdego pliku rzeczywistego, ustawia go na N i zrywa z pętli for dla zwiększenia wydajności. Jeśli było zero plików, pozostaje on jako Y.

+0

Jeśli jesteś/ls -a/ls -A/', potrzeba" egrep "znika. – ikegami

+0

dlaczego używać egrep, gdy można pozostać w bash? również nie ma potrzeby porównywania wyniku z pustym łańcuchem. to jest droższe niż musi być. –

+0

@tristan, to pewnie dlatego masz akceptację raczej niż ja :-) Pamiętaj jednak, że żadne z moich rozwiązań powyżej, a nie twoje, pozostaje "w bashu". Wszystkie wywołują 'ls' i zewnętrzny plik wykonywalny. Dodam rozwiązanie bashowe, ale będzie to brzydkie. – paxdiablo

1

nie mam dobrego czystego roztworu sh/bash, ale to jest łatwe do zrobienia w Perlu:

#!/usr/bin/perl 

use strict; 
use warnings; 

die "Usage: $0 dir\n" if scalar @ARGV != 1 or not -d $ARGV[0]; 
opendir my $DIR, $ARGV[0] or die "$ARGV[0]: $!\n"; 
my @files = readdir $DIR; 
closedir $DIR; 
if (scalar @files == 2) { # . and .. 
    exit 0; 
} 
else { 
    exit 1; 
} 

nazwać to coś emptydir i umieścić go gdzieś w $PATH, a następnie:

if emptydir dir ; then 
    echo "dir is empty" 
else 
    echo "dir is not empty" 
fi 

Umiera z komunikatem o błędzie, jeśli nie podano mu żadnych argumentów, dwóch lub więcej argumentów lub argumentu, który nie jest katalogiem; zmiana jest dość łatwa, jeśli preferujesz inne zachowanie.

+1

'exit (zdefiniowane (glob quotemeta ($ ARGV [0] //". ")."/* ")? 0: 1)' – ikegami

+0

oh, moje nie sprawdza ukrytych plików. – ikegami

0

Dla zabawy:

if (shopt -s nullglob ; perl -e'exit [email protected]' ./*) ; then 
    echo 'Found some!' 
fi 

(nie sprawdza ukrytych plików)

1
# tested on Linux BASH 

directory=$1 

if test $(stat -c %h $directory) -gt 2; 
then 
    echo "not empty" 
else 
    echo "empty" 
fi 
+0

Możesz uzyskać fałszywy negatyw w katalogach głównych, ale fajnie. – ikegami