Bagaimana saya bisa menggunakan penghitung kata ( wc) dan perpipaan untuk menghitung berapa banyak file atau direktori dalam /usr/bindirektori?
Bagaimana saya bisa menggunakan penghitung kata ( wc) dan perpipaan untuk menghitung berapa banyak file atau direktori dalam /usr/bindirektori?
Jawaban:
Salah satu pendekatan akan digunakan lsuntuk memberi kami daftar file, tetapi kami ingin daftar ini dijamin hanya menampilkan 1 file atau direktori per baris. The -1switch akan melakukan ini untuk kita.
$ ls -1
dir1
dir2
dir3
fileA
fileB
fileC
Buat data sampel di atas dalam direktori kosong.
$ mkdir dir{1..3}
$ touch file{A..C}
Periksa:
$ ls
dir1 dir2 dir3 fileA fileB fileC
Sekarang untuk menghitung, Anda dapat menggunakan wc -luntuk menghitung jumlah baris, yang sesuai dengan file atau direktori dalam ls -1output.
$ ls -1 | wc -l
6
(Namun perlu dicatat bahwa itu tidak termasuk file yang tersembunyi)
Untuk menghitung file atau direktori, Anda perlu sedikit mengubah taktik Anda. Dalam hal ini saya akan menggunakan ls -lkarena ini menunjukkan apa itu direktori dan file apa.
$ ls -l
total 12
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileC
Kemudian kita dapat menggunakan grepuntuk menyaring direktori atau tidak-direktori seperti:
# directories
$ ls -l | grep "^d"
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
# regular files
$ ls -l | grep "^-"
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileC
Sekarang cukup gunakan wc -llagi untuk menghitung di atas:
# directories
$ ls -l | grep "^d" | wc -l
3
# regular files
$ ls -l | grep "^-" | wc -l
3
Meskipun, Anda dapat menghindari wcsama sekali, dan menggunakan grep's -cpilihan:
$ ls -l | grep -c '^d'
(Sekali lagi, file tersembunyi tidak termasuk. Perhatikan bahwa direktori dan reguler adalah dua jenis file. Ada lebih banyak lagi seperti pipa bernama, tautan simbolik, perangkat, soket ...).
Jika Anda perlu menemukan file dan direktori secara rekursif di bawah /usr/binmaka Anda mungkin ingin mengubah taktik sepenuhnya dan menggunakan alat lain yang disebut find.
$ find /usr/bin | wc -l
4632
(meskipun di atas /usr/binitu sendiri termasuk dalam hitungan)
Teknik yang sama yang saya gunakan di atas dapat digunakan lsuntuk melakukan sesuatu yang serupa tetapi lsumumnya bukan alat yang baik untuk mem-parsing output. finddi sisi lain dibangun untuk ini, dan menawarkan sakelar untuk menemukan file atau direktori.
# find files
$ find /usr/bin -type f
# find directories
$ find /usr/bin -type d
(perhatikan bahwa saat ini, findsudah termasuk file tersembunyi (kecuali .dan ..)).
Saya tidak pernah tahu mengapa karakter baris baru adalah karakter hukum untuk digunakan saat membuat nama file atau nama direktori. Jadi metode yang dibahas di atas menggunakan wcdan lstidak akan menentangnya, jadi gunakan metode itu dengan mengingatnya.
Buat direktori & nama file dengan baris baru.
$ mkdir $'dir4\n5'
$ touch $'fileD\nE'
ls menunjukkannya dengan benar:
$ ls -1
dir1
dir2
dir3
dir4?5
fileA
fileB
fileC
fileD?E
Tetapi wcmenghitung direktori dan file yang berisi baris baru sebagai 2 item, bukan satu.
$ ls -1 | wc -l
10
Salah satu metode untuk mengatasi ini, jika menggunakan implementasi GNU findadalah dengan memanfaatkan findkemampuan untuk mencetak sesuatu yang lain di tempat setiap file yang ditemukannya dan kemudian menghitungnya.
$ find . -printf . | wc -c
9
Di sini kami menemukan semua yang ada di direktori saat ini (kecuali ..), dan mencetak sebuah titik ( .) untuk masing-masing, dan kemudian menghitung titik menggunakan wckemampuan untuk menghitung byte alih-alih garis wc -c,.
/usr/binakan diformat dengan baik (dan juga tidak akan berisi spasi, jadi secara teknis Anda bahkan bisa adil echo * | wc -w), perlu dicatat bahwa semua ini akan merusak nama file yang mengandung baris baru.
ls -latau ls -1akan merusak b / c kita menghitung baris, bukan kata-kata! The findbisa pecah, tapi sekali lagi, kita menghitung garis bukan kata-kata.
touch $'foo\nbar'dalam direktori kosong diikuti oleh salah satu perintah Anda (katakanlah ls -1 | wc -l) akan melaporkan dua file daripada satu - karena satu file sejauh dua baris sejauh wcyang bersangkutan. Kecuali jika lsmengganti baris baru dengan beberapa karakter lain (saya pikir tidak, tapi sekali lagi saya tidak dalam posisi untuk menguji sekarang).
wc -cada masalah saat menghitung periode?
Jika Anda ingin mendapatkan rincian jumlah setiap jenis file secara rekursif di bawah beberapa dir, dengan GNU find, Anda bisa melakukan:
find /some/dir/. ! -name . -printf '%y\n' | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
Di /usr/binsistem saya, itu memberi:
3727 regular files
710 symbolic links
Pada /dev:
83 block devices
203 character devices
31 directories
426 symbolic links
1 FIFOs
1 Unix domain sockets
Untuk symlink, jika Anda lebih suka menghitungnya sebagai jenis file yang mereka tuju alih-alih symbolic links, Anda dapat mengubahnya ke:
find /some/dir/. ! -name . -printf '%Y\n' | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/N/broken symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
Yang sekarang memberi saya /usr/bin:
1 directories
4434 regular files
2 broken symbolic links
(symlink yang rusak adalah symlink ke file yang findtidak dapat menentukan jenisnya karena file tersebut tidak ada, atau berada di direktori yang Anda tidak memiliki akses ke atau ada loop dalam resolusi jalur file) Dalam kasus saya, 2 tempat symlink ke file yang sekarang hilang).
Tak satu pun dari mereka dihitung .dan ... Jika Anda ingin mereka dimasukkan (mengapa Anda mau?), Tidak ada cara lain findselain menganggap mereka ada di setiap direktori dan menghitungnya secara sistematis:
find /some/dir/. -printf '%y\n' \( -name . -printf 'd\n' -o \
-type d -printf 'd\nd\n' \) | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
Yang kemudian memberi saya /usr/bin:
2 directories
3727 regular files
710 symbolic links
Jika Anda tidak memiliki akses ke GNU find, Anda dapat menulis ulang yang pertama sebagai:
find /some/dir/. ! -name . \( \
-type f -exec printf '%.0sregular files\n' {} + -o \
-type d -exec printf '%.0sdirectories\n' {} + -o \
-type l -exec printf '%.0ssymbolic links\n' {} + -o \
-type s -exec printf '%.0sUnix domain sockets\n' {} + -o \
-type b -exec printf '%.0sblock devices\n' {} + -o \
-type c -exec printf '%.0scharacter devices\n' {} + -o \
-type p -exec printf '%.0sFIFOs\n' {} + -o \
-exec printf '%.0sothers\n' {} + \) | sort | uniq -c
Sekarang, sebenarnya, kami tidak menghitung file tetapi entri direktori . Direktori seperti /usr/binbiasanya memiliki beberapa entri yang mengarah ke file yang sama. Misalnya, di sini, saya punya:
$ ls -lid /usr/bin/{nvi,nview,nex}
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nex
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nvi
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nview
Itu adalah 3 entri direktori (alias nama file alias tautan keras) ke file yang sama (satu dengan inode 672252. Untuk menghitung file alih-alih entri direktori dan dengan GNU finddan GNU uniq(mengabaikan .dan ..file yang toh merupakan tautan keras ke direktori lain):
find /some/dir/. ! -name . -printf '%y\t%D:%i\n' |
sort -u |
cut -f1 |
uniq -c |
sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/d/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
Pada saya /usr/bin, itu memberi:
3711 regular files
710 symbolic links
Anda belum mengatakan jika Anda ingin semua file di bawah / usr / bin secara rekursif atau hanya di bawah tingkat pertama. Juga, bagaimana Anda akan mendapatkan kata-kata yang Anda hitung? Cara yang biasa untuk mengetahuinya adalah dengan menjalankan find ke wc. Seperti ini: find / usr / bin | wc-l Find akan menampilkan semua yang ada di sana, direktori & file. Wc-l akan menghitung semua garis dalam output find. Apakah ini tugas kelas? Tidak apa-apa jika itu tapi saya bertanya-tanya mengapa Anda membutuhkan info ini sehingga saya bisa menyesuaikan respon dengan lebih hati-hati. Tolong beri tahu saya jika Anda membutuhkan lebih banyak. Costa
Di bash, tanpa alat eksternal.
cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"
Di bash, tanpa alat eksternal dan rekursi.
shopt -s globstar; shopt -s dotglob
for dir in **/*/; do
unset d f
for files in "$dir"*; do
[[ -f $files ]] && ((++f))
[[ -d $files ]] && ((++d))
done;
printf '%s\n' "$dir - files: ${f:-0} - directories: ${d:-0}"
done
.maupun ..entri. Anda mungkin ingin memisahkan file vs file biasa.