Memeriksa dari skrip shell jika direktori berisi file

116

Dari skrip shell, bagaimana cara memeriksa apakah direktori berisi file?

Sesuatu yang mirip dengan ini

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

tetapi yang berfungsi jika direktori berisi satu atau beberapa file (yang di atas hanya berfungsi dengan tepat 0 atau 1 file).

ionn
sumber
Untuk apa nilainya contoh Anda, baik melakukan apa yang Anda inginkan di ksh dan zsh
Dave Webb
2
@DaveWebb Tidak. Jika glob diperluas menjadi lebih dari satu kata, pengujian zsh melaporkan 'test: too many arguments'.
Jens
"huzzah" berarti "direktori tidak kosong".
funroll
Jika direktori hanya berisi subdirektori kosong, apakah itu dianggap sebagai "berisi file"?
Keith Thompson
Terkait: Menemukan direktori kosong UNIX
Joseph Holsten

Jawaban:

72

Solusi yang digunakan sejauh ini ls. Inilah solusi semua bash:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
Bruno De Fraine
sumber
8
selama Anda ingat untuk menyetel opsi kembali ke nilai aslinya di akhir skrip :)
Jean
Ini adalah versi yang sedikit lebih baik yang menangani ulang pengaturan bash:shopt -q nullglob || resetnullglob=1; shopt -s nullglob; shopt -q dotglob || resetdotglob=1; shopt -s dotglob; files=(/some/dir/*); [ "$files" ] && echo "wowzers"; [ "$resetdotglob" ] && shopt -u dotglob; [ "$resetnullglob" ] && shopt -u nullglob;
user123444555621
12
Mengapa tidak menggunakan subkulit untuk mengatur ulang pengaturan:files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
teambob
7
@teambob jika menggunakan sub-shell: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) maka pernyataan if harus berubah menjadi if [ ${#files} -gt 0 ];atau mungkin Anda lupa () di sekitar perintah sub-shell? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk
2
@stoutyhk $ (...) mengembalikan pengaturan, tidak diperlukan subkulit terpisah. Menggunakan $ (...) memunculkan instance baru dari shell. Lingkungan instance baru ini akan dibuang setelah perintah selesai. Edit: Menemukan referensi tldp.org/LDP/abs/html/commandsub.html "Substitusi perintah memanggil subkulit."
teambob
140

Tiga trik terbaik


shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))

Trik ini 100% bashdan memanggil (memunculkan) sub-shell. Ide ini dari Bruno De Fraine dan ditingkatkan dengan komentar teambob .

files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
  echo "contains files"
else 
  echo "empty (or does not exist or is a file)"
fi

Catatan: tidak ada perbedaan antara direktori kosong dan yang tidak ada (dan bahkan jika jalur yang diberikan adalah file).

Ada alternatif serupa dan detail lebih lanjut (dan lebih banyak contoh) di FAQ 'resmi' untuk saluran IRC #bash :

if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi

[ -n "$(ls -A your/dir)" ]

Trik ini terinspirasi dari artikel nixCraft yang diposting pada tahun 2007. Tambahkan 2>/dev/nulluntuk menekan kesalahan keluaran "No such file or directory".
Lihat juga jawaban Andrew Taylor (2008) dan jawaban gr8can8dian (2011).

if [ -n "$(ls -A your/dir 2>/dev/null)" ]
then
  echo "contains files (or is a file)"
else
  echo "empty (or does not exist)"
fi

atau versi bashism satu baris:

[[ $(ls -A your/dir) ]] && echo "contains files" || echo "empty"

Catatan: ls kembali $?=2jika direktori tidak ada. Tetapi tidak ada perbedaan antara file dan direktori kosong.


[ -n "$(find your/dir -prune -empty)" ]

Trik terakhir ini terinspirasi dari jawaban gravstar ini di mana -maxdepth 0digantikan oleh -prunedan diperbaiki oleh phils komentar 's.

if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

variasi menggunakan -type d:

if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
  echo "empty directory"
else
  echo "contains files (or does not exist or is not a directory)"
fi

Penjelasan:

  • find -prunemirip find -maxdepth 0dengan menggunakan lebih sedikit karakter
  • find -empty mencetak direktori dan file kosong
  • find -type d mencetak direktori saja

Catatan: Anda juga dapat mengganti [ -n "$(find your/dir -prune -empty)" ]hanya dengan versi singkat di bawah ini:

if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

Kode terakhir ini berfungsi pada sebagian besar kasus, tetapi ketahuilah bahwa jalur berbahaya dapat mengekspresikan perintah ...

olibre.dll
sumber
2
Saya rasa Anda dapat menyederhanakan opsi find [ -n "$(find "your/dir" -prune -empty)" ], untuk menghindari pengulangan jalur direktori.
phils
Saat menggunakan if [ ``ls -A your/dir`` ]skrip, saya sampai pada kesimpulan bahwa itu berfungsi dengan baik untuk direktori dengan 0, 1 atau 2 subdirektori, tetapi gagal untuk direktori dengan lebih dari 2 subdirektori. line 17: [: 20150424-002813: unary operator expecteddi mana 20150424-002813salah satu nama direktorinya. Cangkang bekas itu /bin/bash/. Saya akhirnya mengubahnya menjadils "$destination" | tail -1
Christophe De Troyer
Hai @ChristopheDeTroyer, saya tidak dapat mereproduksi masalah Anda. Di sisi saya if [ ``ls -A my/dir`` ]keluar karena kesalahan bash: [: -A: binary operator expected. Diuji pada bash versi 4.1.2 dan 4.2.53.
olibre
1
Yah, saya terutama termotivasi untuk berkomentar karena ketidakkonsistenan yang dirasakan (karena -nvarian ada di tajuk utama tetapi kemudian tidak di paragraf di bawah). Jadi, ya, tidak apa-apa.
maxschlepzig
1
Saya menggunakan solusi -n Anda, masih skrip saya masih mengeluh tentang ini ls: cannot access '/path': No such file or directory. Adakah cara agar saya bisa menyembunyikan pesan ini? Saya ingin gagal diam-diam di sana.
Freedo
48

Bagaimana dengan yang berikut ini:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

Dengan cara ini tidak perlu membuat daftar lengkap dari isi direktori. Itu readadalah untuk membuang keluaran dan membuat ekspresi mengevaluasi menjadi benar hanya ketika sesuatu dibaca (yaitu /some/dir/ditemukan kosong oleh find).

mweerden
sumber
3
atau sederhananyafind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
doubleDown
5
+1 Ini solusi paling elegan. Ini tidak melibatkan penguraian lsoutput dan tidak bergantung pada fitur shell non-default.
7
Itu, bagaimanapun, bergantung pada non-standar -maxdepthdan -emptypendahuluan.
chepner
21

Mencoba:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
Greg Hewgill
sumber
Ini berhasil untuk saya, tetapi saya tidak dapat memformat pesan sialan ini !!! <br> ekspor tmp = /bin/ls <some_dir>/* 2> /dev/nullif [! -z "$ tmp"]; lalu gema Sesuatu yang ada di sana fi
AndrewStone
1
Untuk Bash idiot seperti saya, jika Anda ingin memeriksa sebaliknya - bahwa direktorinya kosong - gunakan saja if [-z ls /some/dir/*]; lalu echo "huzzah"; fi
Chris Moschini
4
Anda dapat menggunakan -nalih-alih ! -z(keduanya setara, tetapi mengapa tidak menggunakan formulir yang lebih pendek jika sudah ada).
n. Tanggal
Dengan ZSH contoh ini melontarkan kesalahan, idenya adalah agar kesalahan tidak dilempar ... BigGray% if [ ! -z ls / some / dir / * `]; lalu echo "huzzah"; fi zsh: tidak ada kecocokan yang ditemukan: / some / dir / * `
Hvisage
tidak bekerja untuk saya tanpa tanda kutip ganda ls...di bash
letmutx
15
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}
gr8can8dian.dll
sumber
15

Jaga direktori dengan banyak file! Mungkin perlu beberapa saat untuk mengevaluasi lsperintah.

IMO solusi terbaik adalah yang menggunakan

find /some/dir/ -maxdepth 0 -empty
Gravstar
sumber
8
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi
Andrew Taylor
sumber
6

Bisakah Anda membandingkan hasilnya?

 ls -A /some/dir | wc -l
DGM
sumber
4
# Memeriksa apakah direktori berisi file tidak tersembunyi.
#
# penggunaan: jika kosong "$ HOME"; lalu echo "Selamat datang di rumah"; fi
#
kosong() {
    untuk _ief dalam $ 1 / *; melakukan
        jika [-e "$ _ief"]; kemudian
            return 1
        fi
    selesai
    return 0
}

Beberapa catatan implementasi:

  • The forLoop menghindari panggilan ke eksternalls proses. Itu masih membaca semua entri direktori sekali. Ini hanya dapat dioptimalkan dengan menulis program C yang menggunakan readdir () secara eksplisit.
  • Di test -edalam loop menangkap kasus direktori kosong, dalam hal ini variabel_ief akan diberi nilai "somedir / *". Hanya jika file itu ada, fungsi akan mengembalikan "tidak kosong"
  • Fungsi ini akan bekerja di semua implementasi POSIX. Tetapi ketahuilah bahwa Solaris / bin / sh tidak termasuk dalam kategori itu. Its testimplementasi tidak mendukung -ebendera.
Roland Illig
sumber
1
Ini akan mengabaikan dotfiles di direktori jika dotglobtidak disetel -shopt -s dotglob
l0b0
4

Ini memberi tahu saya jika direktori kosong atau jika tidak, jumlah file di dalamnya.

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi
Daishi
sumber
Adakah yang bisa menjelaskan mengapa saya mendapat suara negatif? Jika saya menulis omong kosong, saya ingin tahu mengapa;)
Daishi
1
Saya tidak meremehkan ini, tetapi kira-kira itu karena Anda mengurai output darils .
Toby Speight
apakah artikel yang ditautkan tidak jelas? Jika ya, kirim email ke penulisnya (bukan saya).
Toby Speight
1
@Tobypeight Saya mengerti maksudnya. Tapi dalam kasus ini saya menghitung baris yang tidak menghitungnya. Ini harus memberikan hasil yang salah hanya jika nama file berisi baris baru. Dan jika nama file mengandung baris baru, sesuatu yang jauh lebih penting pasti ada di suatu tempat;)
Daishi
3

Ini mungkin respons yang sangat terlambat, tetapi ini adalah solusi yang berhasil. Baris ini hanya mengenali keberadaan file! Ini tidak akan memberi Anda positif palsu jika direktori ada.

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi
Steven Penny
sumber
2
dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

Asumsikan Anda tidak memiliki file bernama *ke /any/dir/you/check, itu harus bekerja bash dash posh busybox shdan zshtetapi (untuk zsh) membutuhkan unsetopt nomatch.

Performa harus sebanding dengan lsyang menggunakan *(glob), saya kira akan lambat pada direktori dengan banyak node (saya /usr/bindengan 3000+ file tidak terlalu lambat), akan menggunakan setidaknya memori yang cukup untuk mengalokasikan semua dirs / nama file (dan banyak lagi) karena semuanya diteruskan (diselesaikan) ke fungsi sebagai argumen, beberapa shell mungkin memiliki batasan jumlah argumen dan / atau panjang argumen.

Cara portabel cepat O (1) tanpa sumber daya untuk memeriksa apakah direktori kosong akan menyenangkan untuk dimiliki.

memperbarui

Versi di atas tidak memperhitungkan tersembunyi file / dirs, dalam kasus beberapa tes yang lebih diperlukan, seperti is_emptydari sh Rich (POSIX shell) trik :

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

Tapi, sebaliknya, saya sedang memikirkan sesuatu seperti ini:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

Beberapa kekhawatiran tentang perbedaan garis miring tertinggal dari argumen dan keluaran pencarian ketika dir kosong, dan mengikuti baris baru (tetapi ini harus mudah ditangani), sayangnya di busybox shacara saya apa yang mungkin merupakan bug pada find -> ddpipa dengan keluaran terpotong secara acak ( jika saya menggunakan catoutput selalu sama, sepertinya dddengan argumen count).

Alex
sumber
Saya suka solusi portabel. Saya datang untuk memberikan jawaban yang sama. Saya baru saja menulisnya secara berbeda (kembalikan 2 jika bukan direktori). Selain itu, solusi portabel ini memiliki keuntungan karena tidak memanggil program eksternal apa pun, yang mungkin dianggap sebagai nilai tambah untuk sistem terbatas atau tertanam. Saya hanya khawatir bahwa menggunakan "()" dapat membuat subproses baru (atau setidaknya memaksa untuk menyalin lingkungan dan barang dan kemudian beralih kembali). Lihatlah ini: is_empty () {_d = "$ {1: -.}"; [! -d "$ {_ d}"] && return 2; set - "$ {_ d}" / * "$ {_ d}" /.[!.]* "$ {_ d}" /..?*; ["$ { }" = "$ {_ d} / $ {_ d} /. [!.] * $ {_ d} /..?*"]; };
Diego Augusto Molina
@DiegoAugustoMolina Baru-baru ini dalam sebuah proyek saya harus melakukan tes ini lagi, jika direktori kosong, pada awalnya saya menggunakan python, kemudian karena saya praktis menginstal python hanya untuk itu, saya menerapkan tes di c, pelaksanaannya sangat ekstrim banalitas, saya bertanya-tanya mengapa itu tidak pernah ditambahkan sebagai tes atau sebagai perintah yang berdiri sendiri
Alex
1
Saya juga membutuhkan solusi baru-baru ini untuk masalah ini untuk sistem yang (benar-benar) terbatas. Saya bahkan mengoptimalkan sedikit kode sebelumnya untuk tidak menggunakan variabel tambahan sama sekali. One-liner yang terlihat jelek dan jelek tapi bagus. Layani diri Anda sendiri:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
Diego Augusto Molina
2

ZSH

Saya tahu pertanyaan itu ditandai untuk pesta; tapi, hanya untuk referensi, untuk pengguna zsh :

Uji direktori yang tidak kosong

Untuk memeriksa apakah footidak kosong:

$ for i in foo(NF) ; do ... ; done

dimana, jika footidak kosong, kode di forblok tersebut akan dieksekusi.

Uji direktori kosong

Untuk memeriksa apakah fookosong:

$ for i in foo(N/^F) ; do ... ; done

dimana, jika fookosong, kode di forblok tersebut akan dieksekusi.

Catatan

Kami tidak perlu mengutip direktori di fooatas, tetapi kami dapat melakukannya jika kami perlu:

$ for i in 'some directory!'(NF) ; do ... ; done

Kami juga dapat menguji lebih dari satu objek, meskipun itu bukan direktori:

$ mkdir X     # empty directory
$ touch f     # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done  # echo empty directories
X

Apa pun yang bukan direktori akan diabaikan begitu saja.

Ekstra

Karena kita melakukan globbing, kita dapat menggunakan glob (atau ekspansi brace) apa pun:

$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf                    # create regular file
$ touch X1/f                  # directory X1 is not empty
$ touch Y1/.f                 # directory Y1 is not empty
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo  # print empty directories
X X2 Y Y2

Kami juga dapat memeriksa objek yang ditempatkan dalam sebuah array. Dengan direktori seperti di atas, misalnya:

$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*)                     # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z

Jadi, kita bisa menguji objek yang mungkin sudah disetel dalam parameter array.

Perhatikan bahwa kode di forblok tersebut, jelas, dijalankan pada setiap direktori secara bergantian. Jika ini tidak diinginkan maka Anda cukup mengisi parameter array dan kemudian mengoperasikan parameter itu:

$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories

Penjelasan

Untuk pengguna zsh ada (F)pengualifikasi glob (lihat man zshexpn), yang cocok dengan direktori "full" (tidak kosong):

$ mkdir X Y
$ touch Y/.f        # Y is now not empty
$ touch f           # create a regular file
$ ls -dF *          # list everything in the current directory
f X/ Y/
$ ls -dF *(F)       # will list only "full" directories
Y/

Qualifier (F)mencantumkan objek yang cocok: adalah direktori DAN tidak kosong. Jadi, (^F)kecocokan: bukan direktori ATAU kosong. Jadi, (^F)sendiri juga akan mencantumkan file biasa, misalnya. Jadi, seperti yang dijelaskan di zshexphalaman manual, kita juga membutuhkan (/)pengualifikasi glob, yang hanya mencantumkan direktori:

$ mkdir X Y Z
$ touch X/f Y/.f    # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z

Jadi, untuk memeriksa apakah direktori tertentu kosong, Anda dapat menjalankan:

$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished

dan hanya untuk memastikan bahwa direktori yang tidak kosong tidak akan ditangkap:

$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished

Ups! Karena Ytidak kosong, zsh tidak menemukan kecocokan untuk (/^F)("direktori yang kosong") dan dengan demikian mengeluarkan pesan kesalahan yang mengatakan bahwa tidak ada kecocokan untuk glob yang ditemukan. Oleh karena itu, kami perlu menyembunyikan kemungkinan pesan kesalahan ini dengan(N) pengualifikasi glob:

$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished

Jadi, untuk direktori kosong kita membutuhkan qualifier (N/^F), yang bisa dibaca sebagai: "jangan peringatkan saya tentang kegagalan, direktori yang tidak penuh".

Demikian pula, untuk direktori yang tidak kosong kita memerlukan qualifier (NF), yang juga bisa kita baca sebagai: "jangan peringatkan saya tentang kegagalan, direktori lengkap".

Zorawar
sumber
1

Saya terkejut panduan wooledge tentang direktori kosong belum disebutkan. Panduan ini, dan semua wooledge benar-benar, harus dibaca untuk pertanyaan tipe shell.

Catatan dari halaman itu:

Jangan pernah mencoba mengurai keluaran ls. Bahkan solusi ls -A dapat rusak (misalnya pada HP-UX, jika Anda root, ls -A melakukan kebalikan dari apa yang dilakukannya jika Anda bukan root - dan tidak, saya tidak dapat membuat sesuatu yang luar biasa bodoh).

Faktanya, seseorang mungkin ingin menghindari pertanyaan langsung sama sekali. Biasanya orang ingin mengetahui apakah sebuah direktori kosong karena mereka ingin melakukan sesuatu yang melibatkan file di dalamnya, dll. Perhatikan pertanyaan yang lebih besar. Misalnya, salah satu contoh berbasis penemuan ini mungkin merupakan solusi yang tepat:

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

Paling umum, yang benar-benar dibutuhkan adalah sesuatu seperti ini:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

Dengan kata lain, orang yang mengajukan pertanyaan mungkin mengira pengujian direktori kosong yang eksplisit diperlukan untuk menghindari pesan kesalahan seperti mympgviewer: ./*.mpg: Tidak ada file atau direktori seperti itu padahal sebenarnya tidak diperlukan pengujian seperti itu.

uskup
sumber
1

Variasi kecil dari jawaban Bruno :

files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ] 
then
    echo "Contains files"
else
    echo "Empty"
fi

Ini bekerja untuk saya

loockass
sumber
1

Mengambil petunjuk (atau beberapa) dari jawaban olibre, saya suka fungsi Bash:

function isEmptyDir {
  [ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}

Karena sementara itu membuat satu subkulit, itu sedekat mungkin dengan solusi O (1) seperti yang saya bayangkan dan memberinya nama membuatnya dapat dibaca. Saya kemudian bisa menulis

if isEmptyDir somedir
then
  echo somedir is an empty directory
else
  echo somedir does not exist, is not a dir, is unreadable, or is  not empty
fi

Adapun O (1) ada kasus pencilan: jika direktori besar memiliki semua atau semua kecuali entri terakhir dihapus, "temukan" mungkin harus membaca semuanya untuk menentukan apakah itu kosong. Saya percaya bahwa kinerja yang diharapkan adalah O (1) tetapi kasus terburuk adalah linier dalam ukuran direktori. Saya belum mengukur ini.

ForDummies
sumber
0

Sejauh ini saya belum melihat jawaban yang menggunakan grep yang menurut saya akan memberikan jawaban yang lebih sederhana (dengan tidak terlalu banyak simbol aneh!). Berikut adalah cara saya memeriksa apakah ada file yang ada di direktori menggunakan bourne shell:

ini mengembalikan jumlah file dalam direktori:

ls -l <directory> | egrep -c "^-"

Anda dapat mengisi jalur direktori tempat direktori ditulis. Paruh pertama pipa memastikan bahwa karakter pertama dari keluaran adalah "-" untuk setiap file. egrep kemudian menghitung jumlah baris yang dimulai dengan simbol itu menggunakan ekspresi reguler. sekarang yang harus Anda lakukan adalah menyimpan nomor yang Anda peroleh dan membandingkannya menggunakan kutipan latar seperti:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x adalah variabel pilihan Anda.

Jecht Tire
sumber
0

Mencampur hal-hal pangkas dan jawaban terakhir, saya harus

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

yang berfungsi untuk jalur dengan spasi juga

Laurent G
sumber
0

Jawaban sederhana dengan bash :

if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;
Thomas Steinbach
sumber
0

Saya akan memilih find:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

Ini memeriksa output dari hanya mencari file di direktori, tanpa melalui subdirektori. Kemudian ia memeriksa output menggunakan -zopsi yang diambil dari man test:

   -z STRING
          the length of STRING is zero

Lihat beberapa hasil:

$ mkdir aaa
$ dir="aaa"

Dir kosong:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Hanya dirs di dalamnya:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

File di direktori:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

File di subdirektori:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
fedorqui 'JADI berhenti merugikan'
sumber
0

Dengan beberapa solusi, saya dapat menemukan cara sederhana untuk mengetahui apakah ada file dalam sebuah direktori. Ini dapat diperluas dengan perintah grep untuk memeriksa secara spesifik file .xml atau .txt, dll. Contoh:ls /some/dir | grep xml | wc -l | grep -w "0"

#!/bin/bash
if ([ $(ls /some/dir | wc -l  | grep -w "0") ])
    then
        echo 'No files'
    else
        echo 'Found files'
fi
chanaka777
sumber
-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
Toby
sumber
Saya suka yang ini karena tidak ada tanda kutip atau tanda kurung yang muncul pada perintah.
Dave Webb
Berhati-hatilah untuk tidak menggunakan ini jika Anda mengaturnya nullglob, karena lsperintah akan berhasil.
Steve Kehlet
Tidak akan berfungsi di semua lingkungan jika direktori memiliki file titik.
Diego Augusto Molina
-1

untuk menguji direktori target tertentu

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;
ND
sumber
-1

Coba dengan command find. Tentukan direktori hardcode atau sebagai argumen. Kemudian mulai temukan untuk mencari semua file di dalam direktori. Periksa apakah return of find null. Gema data temukan

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi
igiannak
sumber
Jika direktori memiliki direktori kosong atau file tidak biasa (soket, perangkat char, symlink, dll.) Di dalamnya, ini tidak akan berfungsi. Direktori akan dilaporkan kosong.
Diego Augusto Molina
@DiegoAugustoMolina jika saya mengerti dengan benar dalam pertanyaan itu adalah bahwa kami mencari untuk memeriksa apakah file ada (sebagai file dalam literal) itulah alasan argumen -f digunakan. tetapi komentar Anda masih berlaku.
igiannak
-2

Saya tidak suka ls - Asolusi yang diposting. Kemungkinan besar Anda ingin menguji apakah direktori tersebut kosong karena Anda tidak ingin menghapusnya. Berikut ini yang melakukannya. Namun, jika Anda hanya ingin mencatat file kosong, pasti menghapus dan membuatnya lebih cepat kemudian mendaftar file yang mungkin tidak terbatas?

Ini harus bekerja ...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi
thejartender
sumber
4
Ini tidak berfungsi jika pengguna tidak memiliki izin menulis ${target}/...
Jens
Hanya ide yang buruk untuk membuat tes menjadi destruktif. Antara lain, memperkenalkan kondisi balapan.
4dummies
-2

Bekerja dengan baik untuk saya ini (saat dir ada):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

Dengan cek lengkap:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi
jerzyjerzy
sumber