簡體   English   中英

遞歸計數 Linux 目錄中的文件

[英]Recursively counting files in a Linux directory

如何遞歸計算 Linux 目錄中的文件?

我找到了這個:

find DIR_NAME -type f ¦ wc -l

但是當我運行它時,它返回以下錯誤。

查找:路徑必須在表達式之前:¦

這應該有效:

find DIR_NAME -type f | wc -l

解釋:

  • -type f僅包含文件。
  • | 而不是¦ )將find命令的標准輸出重定向到wc命令的標准輸入。
  • wc (字數的縮寫)計算其輸入(文檔)中的換行符、字數和字節數。
  • -l只計算換行符。

筆記:

  • DIR_NAME替換為. 在當前文件夾中執行命令。
  • 您還可以刪除-type f以在計數中包含目錄(和符號鏈接)。
  • 如果文件名可以包含換行符,則此命令可能會過度計數。

解釋為什么您的示例不起作用:

在您顯示的命令中,您不使用“管道”( | )來連接兩個命令,而是使用 shell 無法識別為命令或類似內容的斷線( ¦ )。 這就是您收到該錯誤消息的原因。

對於當前目錄:

find -type f | wc -l

如果您想了解當前目錄下每個目錄中有多少文件:

for i in */ .*/ ; do 
    echo -n $i": " ; 
    (find "$i" -type f | wc -l) ; 
done

當然,這可以全部放在一條線上。 括號闡明了應該觀察誰的輸出wc -l (在這種情況下是find $i -type f )。

在我的電腦上, rsyncfind | wc -l find | wc -l在接受的答案中:

$ rsync --stats --dry-run -ax /path/to/dir /tmp

Number of files: 173076
Number of files transferred: 150481
Total file size: 8414946241 bytes
Total transferred file size: 8414932602 bytes

第二行包含文件數,在上面的示例中為 150,481。 作為獎勵,您還可以獲得總大小(以字節為單位)。

評論:

  • 第一行是文件、目錄、符號鏈接等的計數,這就是它比第二行大的原因。
  • --dry-run (或簡稱-n )選項對於不實際傳輸文件很重要!
  • 我使用-x選項來“不跨越文件系統邊界”,這意味着如果你為/執行它並且你連接了外部硬盤,它只會計算根分區上的文件。

您可以使用

$ tree

安裝包后

$ sudo apt-get install tree

(在 Debian / Mint / Ubuntu Linux 機器上)。

該命令不僅顯示文件數,還分別顯示目錄數。 選項 -L 可用於指定最大顯示級別(默認情況下,它是目錄樹的最大深度)。

通過提供-a選項也可以包含隱藏文件。

由於 UNIX 中的文件名可能包含換行符(是的,換行符), wc -l可能會計算太多文件。 我會為每個文件打印一個點,然后計算點數:

find DIR_NAME -type f -printf "." | wc -c

注意: -printf選項僅適用於來自 GNU findutils 的 find。 您可能需要安裝它,例如在 Mac 上。

將這里的幾個答案結合在一起,最有用的解決方案似乎是:

find . -maxdepth 1 -type d -print0 |
xargs -0 -I {} sh -c 'echo -e $(find "{}" -printf "\n" | wc -l) "{}"' |
sort -n

它可以處理奇怪的事情,例如包含空格括號甚至換行的文件名。 它還按文件數對輸出進行排序。

您可以增加-maxdepth之后的數字來計算子目錄。 請記住,這可能需要很長時間,特別是如果您有一個高度嵌套的目錄結構和一個高-maxdepth數。

如果您想知道當前工作目錄中存在多少文件和子目錄,您可以使用此單行

find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find {} | wc -l) {}' | sort -n

這將適用於 GNU 風格,並且只需從 BSD linux(例如 OSX)的 echo 命令中省略 -e。

您可以使用命令ncdu 它將遞歸地計算一個 Linux 目錄包含多少個文件。 這是一個輸出示例:

在此處輸入圖像描述

它有一個進度條,如果您有很多文件,這很方便:

在此處輸入圖像描述

在 Ubuntu 上安裝它:

sudo apt-get install -y ncdu

基准測試:我使用https://archive.org/details/cv_corpus_v1.tar(380390個文件,11 GB)作為必須計算文件數量的文件夾。

  • find . -type f | wc -l find . -type f | wc -l : 大約 1m20s 完成
  • ncdu : 大約 1m20s 完成

如果您需要遞歸計算特定文件類型,您可以執行以下操作:

find YOUR_PATH -name '*.html' -type f | wc -l 

-l只是顯示輸出中的行數。

如果您需要排除某些文件夾,請使用-not -path

find . -not -path './node_modules/*' -name '*.js' -type f | wc -l
tree $DIR_PATH | tail -1

樣本輸出:

5309 個目錄,2122 個文件

如果您想避免錯誤情況,請不要讓wc -l查看帶有換行符的文件(這將被視為 2+ 個文件)

例如,假設我們有一個文件,其中包含一個 EOL 字符

> mkdir emptydir && cd emptydir
> touch $'file with EOL(\n) character in it'
> find -type f
./file with EOL(?) character in it
> find -type f | wc -l
2

由於至少 gnu wc似乎沒有讀取/計數空終止列表(文件除外)的選項,因此最簡單的解決方案就是不傳遞文件名,而是每次找到文件時傳遞靜態輸出,例如在與上面相同的目錄中

> find -type f -exec printf '\n' \; | wc -l
1

或者,如果您的find支持它

> find -type f -printf '\n' | wc -l
1 

要確定當前目錄中有多少文件,請輸入ls -1 | wc -l ls -1 | wc -l 這使用wc來計算ls -1輸出中的行數(-l) 它不計算點文件。 請注意,我在本 HOWTO 的先前版本中使用的ls -l (這是一個“L”而不是前面示例中的“1”)實際上會給你一個比實際計數大一的文件計數。 感謝 Kam Nejad 的這一點。

如果你只想計算文件而不包括符號鏈接(只是你可以做的一個例子),你可以使用ls -l | grep -v ^l | wc -l ls -l | grep -v ^l | wc -l ls -l | grep -v ^l | wc -l (這次是“L”而不是“1”,我們想要一個“長”列表)。 grep檢查以“l”開頭的任何行(表示鏈接),並丟棄該行 (-v)。

相對速度:“ls -1 /usr/bin/ | wc -l”在卸載的 486SX25 上大約需要 1.03 秒(這台機器上的 /usr/bin/ 有 355 個文件)。 ls -l /usr/bin/ | grep -v ^l | wc -l ” 大約需要 1.19 秒。

來源: http ://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html

使用 bash:

使用 ( ) 創建一個條目數組並使用 # 獲取計數。

FILES=(./*); echo ${#FILES[@]}

好的,這不會遞歸地計算文件,但我想先展示簡單的選項。 一個常見的用例可能是創建文件的翻轉備份。 這將創建 logfile.1、logfile.2、logfile.3 等。

CNT=(./logfile*); mv logfile logfile.${#CNT[@]}

啟用 bash 4+ globstar的遞歸計數(如@tripleee 所述)

FILES=(**/*); echo ${#FILES[@]}

要遞歸地獲取文件數,我們仍然可以使用 find 以相同的方式。

FILES=(`find . -type f`); echo ${#FILES[@]}

對於名稱中帶有空格的目錄...(基於上面的各種答案)-遞歸打印目錄名稱以及其中的文件數:

find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done

示例(為便於閱讀而格式化):

pwd
  /mnt/Vancouver/Programming/scripts/claws/corpus

ls -l
  total 8
  drwxr-xr-x 2 victoria victoria 4096 Mar 28 15:02 'Catabolism - Autophagy; Phagosomes; Mitophagy'
  drwxr-xr-x 3 victoria victoria 4096 Mar 29 16:04 'Catabolism - Lysosomes'

ls 'Catabolism - Autophagy; Phagosomes; Mitophagy'/ | wc -l
  138

## 2 dir (one with 28 files; other with 1 file):
ls 'Catabolism - Lysosomes'/ | wc -l
  29

使用tree可以更好地可視化目錄結構:

tree -L 3 -F .
  .
  ├── Catabolism - Autophagy; Phagosomes; Mitophagy/
  │   ├── 1
  │   ├── 10
  │   ├── [ ... SNIP! (138 files, total) ... ]
  │   ├── 98
  │   └── 99
  └── Catabolism - Lysosomes/
      ├── 1
      ├── 10
      ├── [ ... SNIP! (28 files, total) ... ]
      ├── 8
      ├── 9
      └── aaa/
          └── bbb

  3 directories, 167 files

man find | grep mindep
  -mindepth levels
    Do not apply any tests or actions at levels less than levels
    (a non-negative integer).  -mindepth 1 means process all files
    except the starting-points.

ls -p | grep -v / ls -p | grep -v / (在下面使用)來自https://unix.stackexchange.com/questions/48492/list-only-regular-files-but-not-directories-in-current-directory的答案 2

find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Catabolism - Lysosomes: 28
./Catabolism - Lysosomes/aaa: 1

應用程序:我想在數百個目錄中找到最大文件數(所有深度 = 1)[下面的輸出再次格式化以提高可讀性]:

date; pwd
    Fri Mar 29 20:08:08 PDT 2019
    /home/victoria/Mail/2_RESEARCH - NEWS

time find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done > ../../aaa
    0:00.03

[victoria@victoria 2_RESEARCH - NEWS]$ head -n5 ../../aaa
    ./RNA - Exosomes: 26
    ./Cellular Signaling - Receptors: 213
    ./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
    ./Stress - Physiological, Cellular - General: 261
    ./Ancient DNA; Ancient Protein: 34

[victoria@victoria 2_RESEARCH - NEWS]$ sed -r 's/(^.*): ([0-9]{1,8}$)/\2: \1/g' ../../aaa | sort -V | (head; echo ''; tail)

    0: ./Genomics - Gene Drive
    1: ./Causality; Causal Relationships
    1: ./Cloning
    1: ./GenMAPP 2
    1: ./Pathway Interaction Database
    1: ./Wasps
    2: ./Cellular Signaling - Ras-MAPK Pathway
    2: ./Cell Death - Ferroptosis
    2: ./Diet - Apples
    2: ./Environment - Waste Management

    988: ./Genomics - PPM (Personalized & Precision Medicine)
    1113: ./Microbes - Pathogens, Parasites
    1418: ./Health - Female
    1420: ./Immunity, Inflammation - General
    1522: ./Science, Research - Miscellaneous
    1797: ./Genomics
    1910: ./Neuroscience, Neurobiology
    2740: ./Genomics - Functional
    3943: ./Cancer
    4375: ./Health - Disease 

sort -V是自然排序。 ...因此,我在這些(Claws Mail)目錄中的最大文件數是 4375 個文件。 如果我左填充( https://stackoverflow.com/a/55409116/1904943 )那些文件名 - 它們都以數字命名,在每個目錄中從 1 開始 - 並填充到 5 個總數字,我應該沒問題.


附錄

查找目錄中文件、子目錄的總數。

$ date; pwd
Tue 14 May 2019 04:08:31 PM PDT
/home/victoria/Mail/2_RESEARCH - NEWS

$ ls | head; echo; ls | tail
Acoustics
Ageing
Ageing - Calorie (Dietary) Restriction
Ageing - Senescence
Agriculture, Aquaculture, Fisheries
Ancient DNA; Ancient Protein
Anthropology, Archaeology
Ants
Archaeology
ARO-Relevant Literature, News

Transcriptome - CAGE
Transcriptome - FISSEQ
Transcriptome - RNA-seq
Translational Science, Medicine
Transposons
USACEHR-Relevant Literature
Vaccines
Vision, Eyes, Sight
Wasps
Women in Science, Medicine

$ find . -type f | wc -l
70214    ## files

$ find . -type d | wc -l
417      ## subdirectories

這里有很多正確的答案。 這是另一個!

find . -type f | sort | uniq -w 10 -c

哪里. 是要查看的文件夾, 10是用於對目錄進行分組的字符數。

我編寫了ffcnt來加速特定情況下的遞歸文件計數:支持范圍映射的旋轉磁盤和文件系統。

它可能比ls或基於find的方法快一個數量級,但 YMMV。

我們可以使用tree命令遞歸地顯示所有文件和文件夾。 以及它在 output 的最后一行顯示文件夾和文件的數量。

$ tree path/to/folder/
path/to/folder/
├── a-first.html
├── b-second.html
├── subfolder
│   ├── readme.html
│   ├── code.cpp
│   └── code.h
└── z-last-file.html

1 directories, 6 files

對於 tree 命令中 output 的最后一行,我們可以在它的 output 上使用 tail 命令

$ tree path/to/folder/ | tail -1
1 directories, 6 files

為了安裝樹,我們可以使用下面的命令

$ sudo apt-get install tree

這種過濾格式的替代方法會計算所有可用的 grub 內核模塊:

ls -l /boot/grub/*.mod | wc -l

假設您想要每個目錄的總文件,請嘗試:

for d in `find YOUR_SUBDIR_HERE -type d`; do 
   printf "$d - files > "
   find $d -type f | wc -l
done

對於當前目錄試試這個:

for d in `find . -type d`; do printf "$d - files > "; find $d -type f | wc -l; done;

如果你有長的空間名稱,你需要改變 IFS,像這樣:

OIFS=$IFS; IFS=$'\n'
for d in `find . -type d`; do printf "$d - files > "; find $d -type f | wc -l; done
IFS=$OIFS

根據上面給出的回復和評論,我想出了以下文件計數列表。 特別是它結合了@Greg Bell 提供的解決方案,以及來自@Arch Stanton 和@Schneems 的評論

統計當前目錄和子目錄中的所有文件

function countit { find . -maxdepth 1000000 -type d -print0 | while IFS= read -r -d '' i ; do file_count=$(find "$i" -type f | wc -l) ; echo "$file_count: $i" ; done }; countit | sort -n -r >file-count.txt

計算當前目錄和子目錄中給定名稱的所有文件

function countit { find . -maxdepth 1000000 -type d -print0 | while IFS= read -r -d '' i ; do file_count=$(find "$i" -type f | grep <enter_filename_here> | wc -l) ; echo "$file_count: $i" ; done }; countit | sort -n -r >file-with-name-count.txt

你可以嘗試:

find `pwd` -type f -exec ls -l {} ; | wc -l

查找-type f | wc -l

或(如果目錄是當前目錄)

尋找 。 -類型 f | wc -l

這將完全正常。 簡單的短。 如果要計算文件夾中存在的文件數。

ls | wc -l
ls -l | grep -e -x -e -dr | wc -l 
  1. 長長的清單
  2. 過濾文件和目錄
  3. 計算過濾后的行號

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM