शीर्ष 50 निर्देशिकाओं को अपने पहले स्तर में सबसे अधिक फ़ाइलों / निर्देशिकाओं में खोजें?


21

मैं उन findनिर्देशिकाओं की सूची तैयार करने के लिए कैसे उपयोग कर सकता हूं जिनमें सबसे अधिक संख्या में फाइलें हैं। मैं सूची को उच्चतम से सबसे कम होना चाहूंगा। मैं केवल 1 स्तर की गहराई तक जाने के लिए सूची बनाना चाहूंगा, और मैं आमतौर पर इस कमांड को अपने फाइल सिस्टम के ऊपर से चलाऊंगा, अर्थात /


अलग सवाल (वास्तव में एक ही है, लेकिन अलग तरीके से पूछा गया है), लेकिन क्या इसका जवाब आपके सवाल को हल नहीं करेगा? unix.stackexchange.com/questions/117093/…
पैट्रिक

इसके अलावा संबंधित - stackoverflow.com/questions/15216370/… । यह मैं अपने मूल उत्तर को इनोड प्रश्न पर बंद कर देता हूं, हालांकि मुझे लगता है कि मेरा दृष्टिकोण वहां के लोगों पर कुछ सुधार प्रदान करता है।
ग्रीम

@ पैट्रिक - यह एक लोडेड क्यू है बस ग्रीमेस ए। सच में बिट्स को दूसरे क्यू के ए में दफन किया जाता है, लेकिन यह इस बिट को बाहर लाना था ताकि इसे आगे जाने के लिए संदर्भित किया जा सके।
स्लम

@ तब मैं वास्तव में नहीं मिलता कि यह डुप्लिकेट क्यों नहीं है। उनका जवाब एक और सवाल पर एक जवाब का सिर्फ विस्तार है। तो अब हमारे पास एक ही चीज़ के लिए 3 प्रश्न हैं। मुझे लगता है कि मेरे लिंक पर जवाब भी साफ है। हर निर्देशिका के लिए एक शेल लॉन्च करना सिर्फ गंदा लगता है।
पैट्रिक

1
@ पैट्रिक, मैंने उत्तर को फिर से काम किया है ताकि जीएनयू समाधान हर निर्देशिका के लिए एक नया शेल शुरू न करे। हालांकि ध्यान दें कि यह किसी भी फ़ाइलनाम से निपटने के लिए मानक समाधान है।
ग्रीम

जवाबों:


17

GNU टूल का उपयोग करना:

find / -xdev -type d -print0 |
  while IFS= read -d '' dir; do
    echo "$(find "$dir" -maxdepth 1 -print0 | grep -zc .) $dir"
  done |
  sort -rn |
  head -50

यह दो findकमांड का उपयोग करता है । पहले पाता निर्देशिका और उन्हें पाइप एक करने के लिए whileलूप प्रत्येक निर्देशिका के लिए अगले खोज चलाता है। दूसरे बच्चे की सभी फाइलों / निर्देशिकाओं को पहले स्तर पर सूचीबद्ध करता है जबकि grepउन्हें गिनता है। एक समान नहीं होने के कारण दूसरी खोज के साथ उपयोग करने की grepअनुमति देता -print0है । यह एक नई रेखा के साथ फ़ाइल नाम को दो बार गिना जाता है (हालांकि इसका उपयोग करना और कोई फर्क नहीं पड़ेगा)।wc-zwc-print0

दूसरे findका परिणाम तर्क में रखा गया है echoइसलिए इसे और निर्देशिका नाम को एक ही पंक्ति में आसानी से रखा जा सकता है ( $(..)निर्माण स्वचालित रूप से नई पंक्ति को समाप्त करता है grep)। लाइनों को फिर संख्या और 50 सबसे बड़ी संख्याओं के साथ क्रमबद्ध किया जाता है head

ध्यान दें कि इसमें माउंट पॉइंट्स के शीर्ष स्तर की निर्देशिकाएं भी शामिल होंगी। इसके चारों ओर जाने का एक सरल तरीका यह है कि आप बाइंड माउंट का उपयोग करें और फिर माउंट की निर्देशिका का उपयोग करें। यह करने के लिए:

sudo mount --bind / /mnt

अधिक पोर्टेबल समाधान प्रत्येक निर्देशिका के लिए एक अलग शेल उदाहरण का उपयोग करता है ( यहां भी उत्तर दिया गया है ):

find / -xdev -type d -exec sh -c '
  echo "$(find "$0" | grep "^$0/[^/]*$" | wc -l) $0"' {} \; |
  sort -rn |
  head -50

नमूना उत्पादन:

9225 /var/lib/dpkg/info
6322 /usr/share/qt4/doc/html
4927 /usr/share/man/man3
2301 /usr/share/man/man1
2097 /usr/share/doc
2097 /usr/bin
1863 /usr/lib/x86_64-linux-gnu
1679 /var/cache/apt/archives
1628 /usr/share/qt4/doc/src/images
1614 /usr/share/qt4/doc/html/images
1308 /usr/share/scilab/modules/overloading/macros
1083 /usr/src/linux-headers-3.13-1-common/include/linux
1071 /usr/src/linux-headers-3.13-1-amd64/include/config
847 /usr/include/qt4/QtGui
774 /usr/include/qt4/Qt
709 /usr/share/man/man8
616 /usr/lib
611 /usr/share/icons/oxygen/32x32/actions
608 /usr/share/icons/oxygen/22x22/actions
598 /usr/share/icons/oxygen/16x16/actions
579 /usr/share/bash-completion/completions
574 /usr/share/icons/oxygen/48x48/actions
570 /usr/share/vim/vim74/syntax
546 /usr/share/scilab/modules/m2sci/macros/sci_files
531 /usr/lib/i386-linux-gnu/wine/wine
530 /usr/lib/i386-linux-gnu/wine/wine/fakedlls
496 /etc/ssl/certs
457 /usr/share/mime/application
454 /usr/share/man/man2
450 /usr/include/qt4/QtCore
443 /usr/lib/python2.7
419 /usr/src/linux-headers-3.13-1-common/include/uapi/linux
413 /usr/share/fonts/X11/misc
413 /usr/include/linux
375 /usr/share/man/man5
374 /usr/share/lintian/overrides
372 /usr/share/cmake-2.8/Modules
370 /usr/share/fonts/X11/75dpi
370 /usr/share/fonts/X11/100dpi
356 /usr/share/icons/gnome/24x24/actions
356 /usr/share/icons/gnome/22x22/actions
356 /usr/share/icons/gnome/16x16/actions
353 /usr/share/icons/gnome/48x48/actions
353 /usr/share/icons/gnome/32x32/actions
341 /usr/lib/ghc/ghc-7.6.3
326 /usr/sbin
324 /usr/share/scilab/modules/compatibility_functions/macros
324 /usr/share/scilab/modules/cacsd/macros
320 /usr/share/terminfo/a
319 /usr/share/i18n/locales

11

अद्यतन: मैंने वह सब नीचे किया, जो शांत है, लेकिन मैं इनोड द्वारा निर्देशिकाओं को छांटने का एक बेहतर तरीका लेकर आया हूं:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'

और यदि आप उसी फाइल सिस्टम में रहना चाहते हैं जो आप करते हैं:

du --inodes -xS

यहाँ कुछ उदाहरण आउटपुट है:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

अब LS के साथ:

कई लोगों ने उल्लेख किया कि उनके पास अप-टू-डेट कोरुटिल्स नहीं हैं और --इनोड्स विकल्प उनके पास उपलब्ध नहीं है। तो, यहाँ है:

sudo ls -AiR1U ./ | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

यह मुझे duकमांड के लिए काफी समान परिणाम प्रदान कर रहा है :

डीयू:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

लोकसभा:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

मुझे लगता है कि यह includeबात सिर्फ इस बात पर निर्भर करती है कि कार्यक्रम किस निर्देशिका में दिखता है - क्योंकि वे एक ही फाइल और हार्डलिंक हैं। ऊपर की चीज जैसी किंदा। हालांकि, मैं इसके बारे में गलत हो सकता हूं - और मैं सुधार का स्वागत करता हूं ...

इसके लिए अंतर्निहित विधि यह है कि मैं हर एक lsफ़ाइल नाम को उसके निर्देशिका नाम के साथ sed.उस पर बाद में प्रतिस्थापित कर रहा हूँ ... ठीक है, मैं अपने आप को थोड़ा फजी हूँ। मैं काफी हद तक निश्चित रूप से फाइलों को गिन रहा हूं, जैसा कि आप यहां देख सकते हैं:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

DU DEMO

% du --version
> du (GNU coreutils) 8.22

एक परीक्षण निर्देशिका बनाएं:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

कुछ बच्चे निर्देशिका:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

कुछ फाइलें बनाएं:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

कुछ हार्डलिंक:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

हार्डलिंक को देखें:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

वे अकेले ही गिने जाते हैं, लेकिन एक निर्देशिका ऊपर ले जाओ ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

फिर मैंने नीचे से अपनी भागा स्क्रिप्ट चलायी और:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

और ग्रीम:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

इसलिए मुझे लगता है कि यह दिखाता है कि इनोड को गिनने का एकमात्र तरीका इनोड है। और क्योंकि फाइलों की गिनती का मतलब है कि इनोड्स को गिनना, आप इनकोड को दोगुना नहीं कर सकते - फाइलों को सही तरीके से गिनने के लिए एक से अधिक बार काउंट नहीं किया जा सकता है।

पुराना:

मुझे यह तेज़ लगता है, और यह पोर्टेबल है:

sh <<-\CMD
    { echo 'here='"$PWD"
        printf 'cd "${here}/%s" 2>/dev/null && {
                set -- 
                for glob in ".[!.]*" "[!.]*" ; do
                    set -- $glob "$@" && 
                        [ -e "./$1" ] || shift
                done    
                printf "%%s\\t%%s\\n" $# "$PWD"
        }\n' $( find . -depth -type d 2>/dev/null )
    } | . /dev/stdin |
    sort -rn | 
    sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
CMD

यह -execहर निर्देशिका के लिए नहीं है - यह केवल एक shell प्रक्रिया और एक का उपयोग करता है find। मुझे फ़ाइलों और अन्य सभी set -- $globको शामिल करने का अधिकार अभी भी प्राप्त करना .hiddenहै, लेकिन यह बहुत करीब है और बहुत तेज है। आप cdअपने रूट डायरेक्टरी में सिर्फ उस चेक और ऑफ के लिए जाने चाहिए जो आप जाते हैं।

यहाँ से मेरे आउटपुट रन का एक नमूना है /usr:

14684   /usr/share/man/man3
4322    /usr/lib
3650    /usr/bin
2454    /usr/share/man/man1
1897    /usr/share/fonts/75dpi
...
557     /usr/share/gtk-doc/html/gtk3
557     /usr/share/doc/elementary/latex
539     /usr/lib32/wine/fakedlls
534     /usr/lib/python2.7/site-packages/bzrlib
500     /usr/lib/python3.3/test

मैं sedनीचे के शीर्ष 50 परिणामों पर ट्रिम करने के लिए वहां भी उपयोग करता हूं । headनिश्चित रूप से तेज़ होगा, लेकिन यदि आवश्यक हो तो मैं प्रत्येक पंक्ति को भी ट्रिम कर दूंगा:

...   
159     /home/mikeserv/.config/hom...hhkdoolnlbekcfllmednbl/4.30_0/plugins
154     /home/mikeserv/.config/hom...odhpcledpamjachpmelml/1.3.11_0/js/ace
...

यह क्रूड है, बेशक, लेकिन यह एक सोच थी। मेरे द्वारा उपयोग किया जाने वाला एक और क्रूड डिवाइस डंपिंग और इन 2>stderrदोनों के लिए है । यह केवल निर्देशिकाओं के लिए अनुमतियों की त्रुटियों को देखने की तुलना में क्लीनर है जिसे मैं रूट एक्सेस के बिना नहीं पढ़ सकता हूं - शायद मुझे यह निर्दिष्ट करना चाहिए । खैर, यह एक कार्य प्रगति पर है।findcd2>/dev/nullfind

ठीक है, इसलिए मैंने शेल ग्लब्स को इस तरह से ठीक किया:

for glob in ".[!.]*" "[!.]*" ; do
    set -- $glob "$@" && 
        [ -e "./$1" ] || shift
done    

मैं वास्तव में एक सवाल पूछने जा रहा था कि यह कैसे किया जा सकता है, लेकिन जैसा कि मैं सवाल शीर्षक में टाइप कर रहा था, साइट ने मुझे एक सुझाव से संबंधित प्रश्न पर इशारा किया , जहां, लो और निहारना, स्टीफन ने पहले ही तौला था । इसलिए यह सुविधाजनक था। जाहिरा तौर [^.],पर अच्छी तरह से समर्थन करते हुए, पोर्टेबल नहीं है और आपको !bang.स्टीफन की टिप्पणी में मुझे वहां पाया गया उपयोग करना होगा।

वैसे भी, छिपी हुई फ़ाइलों में बस खींचना पर्याप्त नहीं था, जाहिर है। इसलिए मुझे setशाब्दिक के लिए खोज स्थिति से बचने के लिए दो बार करना पड़ता है $glob। फिर भी, यह प्रदर्शन को प्रभावित नहीं करता है, और यह निर्देशिका में हर फ़ाइल को मज़बूती से जोड़ता है।


@Gememe आप जानते हैं, हमारे समाधानों में से कोई भी वास्तव में इनोड को नहीं संभाल रहा है। उन फ़ाइलों की एक बहुत जो हम सूचीबद्ध कर रहे हैं वे संभवतः एक-दूसरे से कड़ी-कड़ी जुड़ी हुई हैं। मुझे लगता है कि मैं यह कर सकता था ls -iऔर ... मुझे लगता है ... शायद grep... शायद - ठीक है, आप उपयोग कर रहे हैं -xdev,जो एक शुरुआत है ... uniqऔर sort?
mikeserv

आप किस संस्करण को duचला रहे हैं? मेरा duकोई --inodesविकल्प नहीं है।
पैट्रिक

@ पैट्रिक - अपडेट अपडेट करना चाहता है - लेकिन मैंने पोस्ट अपडेट कर दी है।
mikeserv

यह एक खून बह रहा बढ़त सुविधा है :-) मैं 8.21 चला रहा हूं। ऐसा लगता है कि यह 2013-07-27 जोड़ा गया था: git.savannah.gnu.org/gitweb/…
पैट्रिक

इसके अलावा, अगर आपको कोई आपत्ति नहीं है, तो क्या आप इस सवाल पर पोस्ट कर सकते हैं । मुझे नहीं लगता कि मैं इसे स्वीकार करूंगा क्योंकि यह बहुत पोर्टेबल नहीं है, लेकिन मैं इसे बढ़ाऊंगा, और सवाल पर एक और समाधान करना अच्छा होगा।
पैट्रिक

1

केडीरस्टैट जैसे कुछ का उपयोग क्यों नहीं किया गया, हालांकि यह मूल रूप से केडीई के लिए लिखा गया था, लेकिन यह गनोम एस्वेल के साथ ठीक काम करता है। यह आपको फ़ाइल की संख्या / जीआरआई में संबंधित उपयोग और जीयूआई में संबंधित उपयोग का सबसे अच्छा दृश्य देता है।


1
कमांड लाइन विधि की तलाश है।
स्लम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.