Bagaimana saya bisa menggunakan penghitung kata ( wc
) dan perpipaan untuk menghitung berapa banyak file atau direktori dalam /usr/bin
direktori?
Bagaimana saya bisa menggunakan penghitung kata ( wc
) dan perpipaan untuk menghitung berapa banyak file atau direktori dalam /usr/bin
direktori?
Jawaban:
Salah satu pendekatan akan digunakan ls
untuk memberi kami daftar file, tetapi kami ingin daftar ini dijamin hanya menampilkan 1 file atau direktori per baris. The -1
switch 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 -l
untuk menghitung jumlah baris, yang sesuai dengan file atau direktori dalam ls -1
output.
$ 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 -l
karena 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 grep
untuk 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 -l
lagi untuk menghitung di atas:
# directories
$ ls -l | grep "^d" | wc -l
3
# regular files
$ ls -l | grep "^-" | wc -l
3
Meskipun, Anda dapat menghindari wc
sama sekali, dan menggunakan grep
's -c
pilihan:
$ 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/bin
maka Anda mungkin ingin mengubah taktik sepenuhnya dan menggunakan alat lain yang disebut find
.
$ find /usr/bin | wc -l
4632
(meskipun di atas /usr/bin
itu sendiri termasuk dalam hitungan)
Teknik yang sama yang saya gunakan di atas dapat digunakan ls
untuk melakukan sesuatu yang serupa tetapi ls
umumnya bukan alat yang baik untuk mem-parsing output. find
di 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, find
sudah 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 wc
dan ls
tidak 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 wc
menghitung 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 find
adalah dengan memanfaatkan find
kemampuan 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 wc
kemampuan untuk menghitung byte alih-alih garis wc -c
,.
/usr/bin
akan 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 -l
atau ls -1
akan merusak b / c kita menghitung baris, bukan kata-kata! The find
bisa 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 wc
yang bersangkutan. Kecuali jika ls
mengganti baris baru dengan beberapa karakter lain (saya pikir tidak, tapi sekali lagi saya tidak dalam posisi untuk menguji sekarang).
wc -c
ada 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/bin
sistem 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 find
tidak 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 find
selain 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/bin
biasanya 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 find
dan 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.