Jika saya melakukannya ls -1 target_dir | wc -l
, saya mendapatkan jumlah file dalam direktori. Saya menemukan ini agak rumit. Apakah ada cara yang lebih elegan atau ringkas?
ubuntu
command-line
filesystems
codecowboy
sumber
sumber
ls
sudah memberikan jumlah total, lalu bagaimanals -l | head -1
? Jadikan sebagai alias jika Anda menginginkan sesuatu yang lebih pendek.ls -l
menunjukkan ukuran total file, bukan jumlah file.ls | wc -l
akan memberi Anda hitungan yang salah jika ada nama file yang berisi baris baru.stat -c %h .
memberikan informasi yang sama denganls -ld . | cut -d" " -f 2
Jawaban:
Dengan asumsi bash 4+ (yang dimiliki oleh semua versi Ubuntu yang didukung):
Sebut saja sebagai
num_files [dir]
.dir
bersifat opsional, jika tidak menggunakan direktori saat ini. Versi asli Anda tidak menghitung file tersembunyi, demikian juga ini tidak. Jika Anda menginginkan itu,shopt -s dotglob
sebelumnyaset -- *
.Contoh asli Anda tidak hanya menghitung file biasa, tetapi juga direktori dan perangkat lain - jika Anda benar-benar hanya ingin file biasa (termasuk symlink ke file biasa), Anda perlu memeriksanya:
Jika Anda menemukan GNU, sesuatu seperti ini juga merupakan opsi (perhatikan bahwa ini termasuk file tersembunyi, yang tidak dilakukan perintah asli Anda):
(ubah
-type
ke-xtype
jika Anda juga ingin menghitung symlink ke file biasa).sumber
set
gagal jika ada banyak file? Saya pikir Anda mungkin harus menggunakanxargs
dan menjumlahkan kode untuk membuatnya bekerja dalam kasus umum.shopt -s dotglob
jika Anda ingin file mulai.
dihitungset
akan gagal dalam keadaan ini, karena kita sebenarnya tidak melakukanexec
. Intinya, pada sistem saya,getconf ARG_MAX
menghasilkan 262144, tetapi jika saya lakukantest_arg_max() { set -- {1..262145}; echo $#; }; test_arg_max
, itu dengan senang hati menjawab 262145.-maxdepth
bukan POSIX.f=(target_dir/*);echo ${#f[*]}
berfungsi dengan benar untuk file dengan spasi, baris baru, dll. dalam nama.
sumber
ls
adalah multi-kolom hanya jika itu output langsung ke terminal, Anda dapat menghapus opsi "-1", Anda dapat menghapus opsiwc
"-l", hanya membaca nilai pertama (solusi malas, tidak digunakan untuk bukti hukum, investigasi kriminal, misi kritis, ops taktis ..).sumber
wc
untuk mendapatkan jumlah file bahkan dalam kasus sepele, jadi bagaimana ini bahkan sebuah solusi?target
adalah gumpalan yang, ketika diperluas, mencakup beberapa hal yang dimulai dengan tanda hubung. Misalnya, buat direktori baru, masuk ke dalamnya dan lakukantouch -- {1,2,3,-a}.txt && ls *|wc
(NB: gunakanrm -- *.txt
untuk menghapus file-file itu.)wc -l
? Kalau tidak, Anda mendapatkan jumlah baris, kata, dan byte darils
output. Itulah yang dikatakan David Richerby: Anda harus menguraikannya lagi.wc
tidak punya argumen Anda tidak perlu menguraikan jika otak Anda tahu bahwa argumen pertama adalah baris baru.Jika itu adalah kejelasan yang Anda cari (daripada ketepatan yang tepat ketika berurusan dengan file dengan baris baru dalam nama mereka, dll.), Saya sarankan hanya aliasing
wc -l
kelc
("jumlah baris"):Seperti yang telah dicatat orang lain, Anda tidak perlu
-1
opsils
, karena ini otomatis ketikals
menulis ke sebuah pipa. (Kecuali jika Andals
selalu menggunakan mode kolom. Saya pernah melihatnya sebelumnya, tetapi tidak terlalu sering.)Sebuah
lc
alias cukup berguna secara umum, dan untuk pertanyaan ini, jika Anda melihat kasus "hitung direktori saat ini",ls|lc
kira-kira sepintas yang Anda dapat.sumber
Sejauh ini pendekatan Harun adalah satu-satunya pendekatan yang lebih ringkas daripada pendekatan Anda. Versi yang lebih tepat dari pendekatan Anda mungkin terlihat seperti:
Itu secara rekursif mendaftar semua file - bukan direktori - satu per baris termasuk file .dot di bawah direktori saat ini menggunakan shell shell yang diperlukan untuk mengganti karakter yang tidak dapat dicetak. grep menyaring semua daftar direktori induk atau .. atau * / atau baris kosong - jadi seharusnya hanya ada satu baris per file - jumlah total grep yang dikembalikan kepada Anda. Jika Anda ingin direktori anak dimasukkan juga:
Hapus
-R
dalam kedua kasus jika Anda tidak ingin hasil rekursif.sumber
find
. Jika Anda hanya menginginkan hitungan, ini akan berhasil:find -mindepth 1 -maxdepth 1 -printf '\n'|wc -l
(lepaskan kontrol kedalaman untuk mendapatkan hasil rekursif).find . \! -name . -prune | wc -l
- yang masih tidak berfungsi, tentu saja.printf
instruksi mencetak string konstan (baris baru) yang tidak menyertakan nama file sama sekali, sehingga hasilnya tidak tergantung pada nama file yang aneh. Trik ini tidak dapat dilakukan sama sekali denganfind
yang tidak mendukungprintf
, tentu saja.find .//. \!. -name . -prune | grep -c '^\.//\.'
/
menjadi satu-satunya karakter lain yang tidak dapat muncul dalam nama file,.//.
urutannya dijamin akan muncul tepat sekali untuk setiap file, kan? beberapa pertanyaan - mengapa.//.
, dan mengapa-prune
? kapan ini berbedafind . \! -name . | grep -c '^\.'
? (Saya berasumsi bahwa kesalahan.
Anda\!.
adalah kesalahan ketik.)