Bagaimana saya bisa menghitung file dengan ekstensi tertentu, dan direktori di dalamnya?

14

Saya ingin tahu berapa banyak file biasa memiliki ekstensi .cdalam struktur direktori besar yang kompleks, dan juga berapa banyak direktori file ini tersebar. Output yang saya inginkan hanyalah dua angka itu.

Saya telah melihat pertanyaan ini tentang cara mendapatkan jumlah file, tetapi saya perlu tahu jumlah direktori file juga.

  • Nama file saya (termasuk direktori) mungkin memiliki karakter apa saja; mereka mungkin mulai dengan .atau -dan memiliki spasi atau baris baru.
  • Saya mungkin memiliki beberapa symlink yang namanya diakhiri dengan .c, dan symlink ke direktori. Saya tidak ingin symlink diikuti atau dihitung, atau setidaknya saya ingin tahu apakah dan kapan mereka dihitung.
  • Struktur direktori memiliki banyak tingkatan dan direktori tingkat atas (direktori kerja) memiliki setidaknya satu .cfile di dalamnya.

Saya buru-buru menulis beberapa perintah di shell (Bash) untuk menghitungnya sendiri, tapi saya rasa hasilnya tidak akurat ...

shopt -s dotglob
shopt -s globstar
mkdir out
for d in **/; do
     find "$d" -maxdepth 1 -type f -name "*.c" >> out/$(basename "$d")
done
ls -1Aq out | wc -l
cat out/* | wc -l

Ini menghasilkan keluhan tentang pengalihan ambigu, melewatkan file di direktori saat ini, dan tersandung pada karakter khusus (misalnya, output yang diarahkan findmencetak baris baru dalam nama file ) dan menulis sejumlah besar file kosong (oops).

Bagaimana saya dapat dengan andal menyebutkan .cfile - file saya dan direktori yang mengandungnya?


Jika itu membantu, berikut adalah beberapa perintah untuk membuat struktur pengujian dengan nama dan symlink yang buruk:

mkdir -p cfiles/{1..3}/{a..b} && cd cfiles
mkdir space\ d
touch -- i.c -.c bad\ .c 'terrible
.c' not-c .hidden.c
for d in space\ d 1 2 2/{a..b} 3/b; do cp -t "$d" -- *.c; done
ln -s 2 dirlink
ln -s 3/b/i.c filelink.c

Dalam struktur yang dihasilkan, 7 direktori berisi .cfile, dan 29 file biasa diakhiri dengan .c(jika dotglobtidak aktif ketika perintah dijalankan) (jika saya salah hitung, beri tahu saya). Ini adalah angka yang saya inginkan.

Silahkan tidak menggunakan tes khusus ini.

NB: Jawaban dalam bahasa apa pun atau bahasa lain akan diuji & dihargai oleh saya. Jika saya harus menginstal paket baru, tidak ada masalah. Jika Anda tahu solusi GUI, saya mendorong Anda untuk berbagi (tapi saya mungkin tidak akan menginstal sejauh DE untuk mengujinya) :) Saya menggunakan Ubuntu MATE 17.10.

Zanna
sumber
Menulis program untuk menangani kebiasaan pemrograman yang buruk ternyata cukup menantang;)
WinEunuuchs2Unix

Jawaban:

16

Saya belum memeriksa hasilnya dengan symlink tetapi:

find . -type f -iname '*.c' -printf '%h\0' |
  sort -z |
  uniq -zc |
  sed -zr 's/([0-9]) .*/\1 1/' |
  tr '\0' '\n' |
  awk '{f += $1; d += $2} END {print f, d}'
  • The findperintah mencetak nama direktori masing-masing .cfile yang ditemukan.
  • sort | uniq -cakan memberi kita berapa banyak file di setiap direktori ( sortmungkin tidak perlu di sini, tidak yakin)
  • dengan sed, saya mengganti nama direktori dengan 1, sehingga menghilangkan semua karakter aneh yang mungkin, hanya dengan hitungan dan 1sisanya
  • memungkinkan saya untuk mengkonversi ke keluaran yang dipisahkan dengan baris baru dengan tr
  • yang kemudian saya simpulkan dengan awk, untuk mendapatkan jumlah total file dan jumlah direktori yang berisi file-file itu. Perhatikan bahwa di dsini pada dasarnya sama dengan NR. Saya bisa saja menghilangkan memasukkan 1dalam sedperintah, dan hanya dicetak di NRsini, tapi saya pikir ini sedikit lebih jelas.

Hingga tr, data dibatasi oleh NUL, aman terhadap semua nama file yang valid.


Dengan zsh dan bash, Anda dapat menggunakan printf %quntuk mendapatkan string yang dikutip, yang tidak memiliki baris baru di dalamnya. Jadi, Anda mungkin dapat melakukan sesuatu seperti:

shopt -s globstar dotglob nocaseglob
printf "%q\n" **/*.c | awk -F/ '{NF--; f++} !c[$0]++{d++} END {print f, d}'

Namun, meskipun **seharusnya tidak memperluas untuk symlink ke direktori , saya tidak bisa mendapatkan output yang diinginkan pada bash 4.4.18 (1) (Ubuntu 16.04).

$ shopt -s globstar dotglob nocaseglob
$ printf "%q\n" ./**/*.c | awk -F/ '{NF--; f++} !c[$0]++{d++} END {print f, d}'
34 15
$ echo $BASH_VERSION
4.4.18(1)-release

Tapi zsh bekerja dengan baik, dan perintahnya dapat disederhanakan:

$ printf "%q\n" ./**/*.c(D.:h) | awk '!c[$0]++ {d++} END {print NR, d}'
29 7

Dmemungkinkan glob ini untuk memilih file titik, .memilih file biasa (jadi, bukan symlink), dan :hhanya mencetak jalur direktori dan bukan nama file (seperti finditu %h) (Lihat bagian tentang Pembuatan dan Pengubah Nama File ). Jadi dengan perintah awk kita hanya perlu menghitung jumlah direktori unik yang muncul, dan jumlah baris adalah jumlah file.

muru
sumber
Itu luar biasa. Gunakan persis apa yang dibutuhkan dan tidak ada lagi. Terima kasih telah mengajar :)
Zanna
@Zanna jika Anda memposting beberapa perintah untuk membuat ulang struktur direktori dengan symlinks, dan output yang diharapkan dengan symlinks, saya mungkin bisa memperbaikinya.
muru
Saya telah menambahkan beberapa perintah untuk membuat struktur pengujian (rumit seperti biasa) dengan symlink.
Zanna
@Zanna Saya pikir perintah ini tidak perlu penyesuaian untuk mendapatkan 29 7. Jika saya menambahkan -Luntuk find, yang berlangsung hingga 41 10. Output mana yang Anda butuhkan?
muru
1
Menambahkan metode zsh + awk. Mungkin ada beberapa cara untuk mendapatkan zsh sendiri untuk mencetak hitungan untuk saya, tetapi tidak tahu caranya.
muru
11

Python memiliki os.walk, yang membuat tugas-tugas seperti ini mudah, intuitif, dan secara otomatis kuat bahkan dalam menghadapi nama file aneh seperti yang mengandung karakter baris baru. Python 3 script ini, yang saya awalnya diumumkan di chat , dimaksudkan untuk dijalankan di direktori saat ini (tapi itu tidak harus berada di direktori saat ini, dan Anda dapat mengubah apa jalan itu lolos ke os.walk):

#!/usr/bin/env python3

import os

dc = fc = 0
for _, _, fs in os.walk('.'):
    c = sum(f.endswith('.c') for f in fs)
    if c:
        dc += 1
        fc += c
print(dc, fc)

Itu mencetak jumlah direktori yang secara langsung mengandung setidaknya satu file yang namanya berakhir .c, diikuti oleh spasi, diikuti oleh jumlah file yang namanya berakhir .c. File "tersembunyi" - yaitu, file yang namanya dimulai dengan .--adalah termasuk, dan direktori tersembunyi juga dilintasi.

os.walksecara rekursif melintasi hierarki direktori. Itu menyebutkan semua direktori yang secara rekursif dapat diakses dari titik awal yang Anda berikan, menghasilkan informasi tentang masing-masing sebagai tupel dari tiga nilai root, dirs, files,. Untuk setiap direktori yang dilaluinya (termasuk yang pertama yang namanya Anda berikan):

  • rootmemegang pathname dari direktori itu. Perhatikan bahwa ini sama sekali tidak terkait dengan "direktori root" sistem /(dan juga tidak terkait /root) meskipun itu akan pergi ke mereka jika Anda mulai di sana. Dalam hal ini, rootmulai di jalur .--yaitu, direktori saat ini - dan kemana-mana di bawahnya.
  • dirsmenyimpan daftar nama path dari semua subdirektori dari direktori yang namanya disimpan root.
  • filesmemegang daftar nama path dari semua file yang berada di direktori yang namanya saat ini disimpan roottetapi itu bukan direktori sendiri. Perhatikan bahwa ini termasuk jenis file lain selain file biasa, termasuk tautan simbolik, tetapi sepertinya Anda tidak mengharapkan entri seperti itu berakhir .cdan tertarik melihat yang melakukannya.

Dalam hal ini, saya hanya perlu memeriksa elemen ketiga dari tuple, files(yang saya sebut fsdalam naskah). Seperti findperintah, Python os.walkmelintasi subdirektori untuk saya; satu-satunya hal yang harus saya periksa sendiri adalah nama-nama file yang masing-masing berisi. Tidak seperti findperintah, meskipun, os.walksecara otomatis memberi saya daftar nama file tersebut.

Skrip itu tidak mengikuti tautan simbolis. Anda sangat mungkin tidak ingin symlink diikuti untuk operasi seperti itu, karena mereka dapat membentuk siklus, dan karena bahkan jika tidak ada siklus, file dan direktori yang sama dapat dilalui dan dihitung beberapa kali jika mereka dapat diakses melalui symlink yang berbeda.

Jika Anda memang ingin os.walkmengikuti symlink - yang biasanya tidak Anda lakukan - maka Anda bisa meneruskannya followlinks=true. Artinya, alih-alih menulis os.walk('.')Anda bisa menulis os.walk('.', followlinks=true). Saya tegaskan bahwa Anda jarang menginginkan itu, terutama untuk tugas seperti ini di mana Anda secara rekursif menghitung seluruh struktur direktori, tidak peduli seberapa besar itu, dan menghitung semua file di dalamnya yang memenuhi beberapa persyaratan.

Eliah Kagan
sumber
7

Temukan + Perl:

$ find . -type f -iname '*.c' -printf '%h\0' | 
    perl -0 -ne '$k{$_}++; }{ print scalar keys %k, " $.\n" '
7 29

Penjelasan

The findperintah akan menemukan file biasa (sehingga tidak ada symlink atau direktori) dan kemudian mencetak nama direktori mereka berada di ( %h) diikuti oleh \0.

  • perl -0 -ne: baca input baris demi baris ( -n) dan terapkan skrip yang diberikan oleh -euntuk setiap baris. The -0menetapkan garis pemisah input ke \0sehingga kita dapat membaca masukan nol-koma.
  • $k{$_}++: $_adalah variabel khusus yang mengambil nilai dari baris saat ini. Ini digunakan sebagai kunci untuk hash %k , yang nilainya berapa kali setiap baris input (nama direktori) terlihat.
  • }{: ini adalah cara penulisan singkat END{}. Setiap perintah setelah }{akan dieksekusi sekali, setelah semua input telah diproses.
  • print scalar keys %k, " $.\n": keys %kmengembalikan array kunci dalam hash %k. scalar keys %kmemberikan jumlah elemen dalam array itu, jumlah direktori yang terlihat. Ini dicetak bersama dengan nilai saat ini dari $., variabel khusus yang menyimpan nomor baris input saat ini. Karena ini dijalankan di akhir, nomor baris input saat ini akan menjadi jumlah baris terakhir, sehingga jumlah baris terlihat sejauh ini.

Anda dapat memperluas perintah perl untuk ini, untuk kejelasan:

find  . -type f -iname '*.c' -printf '%h\0' | 
    perl -0 -e 'while($line = <STDIN>){
                    $dirs{$line}++; 
                    $tot++;
                } 
                $count = scalar keys %dirs; 
                print "$count $tot\n" '
terdon
sumber
4

Inilah saran saya:

#!/bin/bash
tempfile=$(mktemp)
find -type f -name "*.c" -prune >$tempfile
grep -c / $tempfile
sed 's_[^/]*$__' $tempfile | sort -u | grep -c /

Script pendek ini membuat tempfile, menemukan setiap file di dalam dan di bawah direktori saat ini berakhir .cdan menulis daftar ke tempfile. grepkemudian digunakan untuk menghitung file (mengikuti Bagaimana saya bisa mendapatkan jumlah file dalam direktori menggunakan baris perintah? ) dua kali: Kali kedua, direktori yang terdaftar beberapa kali dihapus menggunakan sort -usetelah menelanjangi nama file dari setiap baris menggunakan sed.

Ini juga berfungsi dengan baik pada baris baru dalam nama file: grep -c /hanya menghitung baris dengan garis miring dan oleh karena itu hanya mempertimbangkan baris pertama dari nama file multi-baris dalam daftar.

Keluaran

$ tree
.
├── 1
   ├── 1
      ├── test2.c
      └── test.c
   └── 2
       └── test.c
└── 2
    ├── 1
       └── test.c
    └── 2

$ tempfile=$(mktemp);find -type f -name "*.c" -prune >$tempfile;grep -c / $tempfile;sed 's_[^/]*$__' $tempfile | sort -u | grep -c /
4
3
pencuci mulut
sumber
4

Shellscript kecil

Saya sarankan bash shellscript kecil dengan dua baris perintah utama (dan variabel filetypeuntuk membuatnya mudah untuk beralih untuk mencari jenis file lainnya).

Itu tidak mencari atau di symlink, hanya file biasa.

#!/bin/bash

filetype=c
#filetype=pdf

# count the 'filetype' files

find -type f -name "*.$filetype" -ls|sed 's#.* \./##'|wc -l | tr '\n' ' '

# count directories containing 'filetype' files

find -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)'" \;|grep 'contains file(s)$'|wc -l

Verbose shellscript

Ini adalah versi yang lebih verbose yang juga mempertimbangkan tautan simbolik,

#!/bin/bash

filetype=c
#filetype=pdf

# counting the 'filetype' files

echo -n "number of $filetype files in the current directory tree: "
find -type f -name "*.$filetype" -ls|sed 's#.* \./##'|wc -l

echo -n "number of $filetype symbolic links in the current directory tree: "
find -type l -name "*.$filetype" -ls|sed 's#.* \./##'|wc -l
echo -n "number of $filetype normal files in the current directory tree: "
find -type f -name "*.$filetype" -ls|sed 's#.* \./##'|wc -l
echo -n "number of $filetype symbolic links in the current directory tree including linked directories: "
find -L -type f -name "*.$filetype" -ls 2> /tmp/c-counter |sed 's#.* \./##' | wc -l; cat /tmp/c-counter; rm /tmp/c-counter

# list directories with and without 'filetype' files (good for manual checking; comment away after test)
echo '---------- list directories:'
 find    -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)' || echo '{} empty'" \;
echo ''
#find -L -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)' || echo '{} empty'" \;

# count directories containing 'filetype' files

echo -n "number of directories with $filetype files: "
find -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)'" \;|grep 'contains file(s)$'|wc -l

# list and count directories including symbolic links, containing 'filetype' files
echo '---------- list all directories including symbolic links:'
find -L -type d -exec bash -c "ls -AF '{}' |grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)' || echo '{} empty'" \;
echo ''
echo -n "number of directories (including symbolic links) with $filetype files: "
find -L -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null && echo '{} contains file(s)'" \; 2>/dev/null |grep 'contains file(s)$'|wc -l

# count directories without 'filetype' files (good for checking; comment away after test)

echo -n "number of directories without $filetype files: "
find -type d -exec bash -c "ls -AF '{}'|grep -e '\.'${filetype}$ -e '\.'${filetype}'\*'$ > /dev/null || echo '{} empty'" \;|grep 'empty$'|wc -l

Uji keluaran

Dari shellscript pendek:

$ ./ccntr 
29 7

Dari verbose shellscript:

$ LANG=C ./c-counter
number of c files in the current directory tree: 29
number of c symbolic links in the current directory tree: 1
number of c normal files in the current directory tree: 29
number of c symbolic links in the current directory tree including linked directories: 42
find: './cfiles/2/2': Too many levels of symbolic links
find: './cfiles/dirlink/2': Too many levels of symbolic links
---------- list directories:
. empty
./cfiles contains file(s)
./cfiles/2 contains file(s)
./cfiles/2/b contains file(s)
./cfiles/2/a contains file(s)
./cfiles/3 empty
./cfiles/3/b contains file(s)
./cfiles/3/a empty
./cfiles/1 contains file(s)
./cfiles/1/b empty
./cfiles/1/a empty
./cfiles/space d contains file(s)

number of directories with c files: 7
---------- list all directories including symbolic links:
. empty
./cfiles contains file(s)
./cfiles/2 contains file(s)
find: './cfiles/2/2': Too many levels of symbolic links
./cfiles/2/b contains file(s)
./cfiles/2/a contains file(s)
./cfiles/3 empty
./cfiles/3/b contains file(s)
./cfiles/3/a empty
./cfiles/dirlink empty
find: './cfiles/dirlink/2': Too many levels of symbolic links
./cfiles/dirlink/b contains file(s)
./cfiles/dirlink/a contains file(s)
./cfiles/1 contains file(s)
./cfiles/1/b empty
./cfiles/1/a empty
./cfiles/space d contains file(s)

number of directories (including symbolic links) with c files: 9
number of directories without c files: 5
$ 
sudodus
sumber
4

Perl sederhana satu liner:

perl -MFile::Find=find -le'find(sub{/\.c\z/ and -f and $c{$File::Find::dir}=++$c}, @ARGV); print 0 + keys %c, " $c"' dir1 dir2

Atau lebih sederhana dengan findperintah:

find dir1 dir2 -type f -name '*.c' -printf '%h\0' | perl -l -0ne'$c{$_}=1}{print 0 + keys %c, " $."'

Jika Anda suka bermain golf dan memiliki Perl terbaru (seperti yang kurang dari satu dekade):

perl -MFile::Find=find -E'find(sub{/\.c$/&&-f&&($c{$File::Find::dir}=++$c)},".");say 0+keys%c," $c"'
find -type f -name '*.c' -printf '%h\0'|perl -0nE'$c{$_}=1}{say 0+keys%c," $."'
Hynek -Pichi- Vychodil
sumber
2

Pertimbangkan untuk menggunakan locateperintah yang jauh lebih cepat daripada findperintah.

Berjalan pada data uji

$ sudo updatedb # necessary if files in focus were added `cron` daily.
$ printf "Number Files: " && locate -0r "$PWD.*\.c$" | xargs -0 -I{} sh -c 'test ! -L "$1" && echo "regular file"' _  {} | wc -l &&  printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -cu | wc -l
Number Files: 29
Number Dirs.: 7

Terima kasih kepada Muru atas jawabannya untuk membantu saya melucuti tautan simbolik dari jumlah file dalam jawaban Unix & Linux .

Terima kasih kepada Terdon untuk jawabannya $PWD(tidak diarahkan pada saya) dalam jawaban Unix & Linux .


Jawaban asli di bawah ini dirujuk oleh komentar

Bentuk pendek:

$ cd /
$ sudo updatedb
$ printf "Number Files: " && locate -cr "$PWD.*\.c$"
Number Files: 3523
$ printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l 
Number Dirs.: 648
  • sudo updatedbPerbarui basis data yang digunakan dengan locateperintah jika .cfile dibuat hari ini atau jika Anda telah menghapus .cfile hari ini.
  • locate -cr "$PWD.*\.c$"temukan semua .cfile di direktori saat ini dan itu adalah anak-anak ( $PWD). Alih-alih mencetak nama file, dan jumlah cetak dengan -cargumen. The rmenspesifikasikan regex bukan default *pattern*yang cocok yang dapat menghasilkan terlalu banyak hasil.
  • locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l. Temukan semua *.cfile di direktori saat ini dan di bawah ini. Hapus nama file dengan sedhanya menyisakan nama direktori. Hitung jumlah file di setiap direktori menggunakan uniq -c. Hitung jumlah direktori dengan wc -l.

Mulai di direktori saat ini dengan satu-liner

$ cd /usr/src
$ printf "Number Files: " && locate -cr "$PWD.*\.c$" &&  printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l
Number Files: 3430
Number Dirs.: 624

Perhatikan bagaimana jumlah file dan jumlah direktori telah berubah. Saya percaya semua pengguna memiliki /usr/srcdirektori dan dapat menjalankan perintah di atas dengan jumlah berbeda tergantung pada jumlah kernel yang diinstal.

Bentuk panjang:

Bentuk panjang mencakup waktu sehingga Anda dapat melihat seberapa cepat locatetelah berakhir find. Bahkan jika Anda harus menjalankannya sudo updatedbbeberapa kali lebih cepat daripada satu find /.

───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/Downloads$ sudo time updatedb
0.58user 1.32system 0:03.94elapsed 48%CPU (0avgtext+0avgdata 7568maxresident)k
48inputs+131920outputs (1major+3562minor)pagefaults 0swaps
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/Downloads$ time (printf "Number Files: " && locate -cr $PWD".*\.c$")
Number Files: 3523

real    0m0.775s
user    0m0.766s
sys     0m0.012s
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/Downloads$ time (printf "Number Dirs.: " && locate -r $PWD".*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l) 
Number Dirs.: 648

real    0m0.778s
user    0m0.788s
sys     0m0.027s
───────────────────────────────────────────────────────────────────────────────────────────

Catatan: Ini semua file di SEMUA drive dan partisi. yaitu kita dapat mencari perintah Windows juga:

$ time (printf "Number Files: " && locate *.exe -c)
Number Files: 6541

real    0m0.946s
user    0m0.761s
sys     0m0.060s
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/Downloads$ time (printf "Number Dirs.: " && locate *.exe | sed 's%/[^/]*$%/%' | uniq -c | wc -l) 
Number Dirs.: 3394

real    0m0.942s
user    0m0.803s
sys     0m0.092s

Saya memiliki tiga partisi Windows 10 NTFS yang terpasang secara otomatis /etc/fstab. Sadarilah menemukan tahu segalanya!

Jumlah Menarik:

$ time (printf "Number Files: " && locate / -c &&  printf "Number Dirs.: " && locate / | sed 's%/[^/]*$%/%' | uniq -c | wc -l)
Number Files: 1637135
Number Dirs.: 286705

real    0m15.460s
user    0m13.471s
sys     0m2.786s

Dibutuhkan 15 detik untuk menghitung 1.637.135 file di 286.705 direktori. YMMV.

Untuk perincian terperinci tentang locatepenanganan regex perintah (tampaknya tidak diperlukan dalam T&J ini tetapi digunakan untuk berjaga-jaga) silakan baca ini: Gunakan "cari" di bawah direktori tertentu?

Bacaan tambahan dari artikel terbaru:

WinEunuuchs2Unix
sumber
1
Ini tidak menghitung file dalam direktori tertentu. Ketika Anda menunjukkan, itu menghitung semua file (atau direktori, atau jenis file lainnya) yang cocok .c(perhatikan bahwa itu akan pecah jika ada file bernama -.cdi direktori saat ini karena Anda tidak mengutip *.c) dan kemudian akan mencetak semua direktori dalam sistem, terlepas dari apakah mereka berisi file .c.
terdon
@terdon Anda dapat melewati direktori ~/my_c_progs/*.c. Ini menghitung 638 direktori dengan .cprogram, total direktori ditampilkan nanti sebagai 286,705. Saya akan merevisi jawaban untuk kutipan ganda `" * .c ". Terima kasih atas tipnya.
WinEunuuchs2Unix
3
Ya, Anda dapat menggunakan sesuatu seperti locate -r "/path/to/dir/.*\.c$", tetapi itu tidak disebutkan di mana pun dalam jawaban Anda. Anda hanya memberikan tautan ke jawaban lain yang menyebutkan ini tetapi tanpa penjelasan tentang bagaimana menyesuaikannya untuk menjawab pertanyaan yang diajukan di sini. Seluruh jawaban Anda difokuskan pada bagaimana cara menghitung jumlah total file dan direktori pada sistem, yang tidak relevan dengan pertanyaan yang diajukan yaitu "bagaimana saya bisa menghitung jumlah file .c, dan jumlah direktori yang mengandung. file dalam direktori spesifik ". Juga, nomor Anda salah, coba contoh di OP.
terdon
@terdon Terima kasih atas masukan Anda. Saya telah meningkatkan jawaban dengan saran Anda dan jawaban yang Anda poskan di situs SE lain untuk $PWDvariabel: unix.stackexchange.com/a/188191/200094
WinEunuuchs2Unix
1
Sekarang Anda harus memastikan bahwa $PWDitu tidak mengandung karakter yang mungkin spesial di regex
muru