wcとパイプを使用して、特定のディレクトリにどれだけのファイルとディレクトリがあるかを確認する方法は?

wcとパイプを使用して、特定のディレクトリにどれだけのファイルとディレクトリがあるかを確認する方法は?

ディレクトリにどれだけのファイルやディレクトリがあるかをwc計算するために単語カウンタ()とパイプを使用する方法は?/usr/bin

答え1

lsこれを行う1つの方法はファイルリストを提供することを使用することですが、リストには1行に1つのファイルやディレクトリだけが表示されるようにしたいと思います。スイッチは-1私たちのためにこれを行います。

$ ls -1
dir1
dir2
dir3
fileA
fileB
fileC

はい

空のディレクトリに上記のサンプルデータを作成します。

$ mkdir dir{1..3}
$ touch file{A..C}

確認する:

$ ls
dir1  dir2  dir3  fileA  fileB  fileC

wc -lこれで、計算するには、出力でファイルまたはディレクトリに対応する行数計算を使用できますls -1

$ ls -1 | wc -l
6

(ただし、隠しファイルは含まれませんのでご注意ください)

ファイルやディレクトリの数を数えますが、一緒に数えません。

ファイルまたはディレクトリの数を数えるには、戦略を少し変更する必要があります。この場合、ls -lディレクトリが何であるか、aaファイルが何であるかを示すため、これを使用します。

はい

$ 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

grepその後、次を使用してディレクトリまたはディレクトリ以外の項目をフィルタリングできます。

# 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

さてwc -l、上記の計算を再利用してください。

# directories
$ ls -l | grep "^d" | wc -l
3

# regular files
$ ls -l | grep "^-" | wc -l
3

ただしwc、これを完全に回避し、次のオプションを使用grepできます-c

$ ls -l | grep -c '^d'

(再び、隠されたファイルは含まれていません。ディレクトリと一般的なファイルは2種類のファイルです。名前付きパイプ、シンボリックリンク、デバイス、ソケットなど、より多くの種類のファイルがあります。)

再帰

ファイルとディレクトリを繰り返し見つける必要がある場合は、/usr/bin戦略を完全に変更し、という別の戦略を使用する必要がありますfind

はい

$ find /usr/bin | wc -l
4632

(上記内容/usr/bin自体も集計に含まれますが)

上記と同じ手法を使用してls同様の操作を実行できますが、ls通常は出力を解析するのに良いツールではありません。findもう一方はこのために作成され、ファイルまたはディレクトリを見つけるためのスイッチを提供します。

# find files
$ find /usr/bin -type f

# find directories
$ find /usr/bin -type d

(今回はfind隠しファイルが含まれています(.および除く..)。

改行?

ファイル名やディレクトリ名を作成するとき、改行がなぜ正当な文字なのか理解できませんでした。したがって、上記の方法を使用しwcてもlsこれらの方法と競合することはありませんので、使用時にこの点に注意してください。

はい

改行を使用してディレクトリとファイル名を作成します。

$ mkdir $'dir4\n5'
$ touch $'fileD\nE'

ls正しく表示してください。

$ ls -1
dir1
dir2
dir3
dir4?5
fileA
fileB
fileC
fileD?E

ただし、wc改行文字を含むディレクトリとファイルは、1つの項目ではなく2つの項目としてカウントされます。

$ ls -1 | wc -l
10

GNU実装を使用している場合、この問題を解決する1つの方法findは、関数を使用してfind見つかったファイルごとに異なるものを印刷してから、そのファイルの数を数えることです。

はい

$ find . -printf . | wc -c
9

ここでは、現在のディレクトリ内のすべての項目(除外..)を検索し、それぞれについて点()を印刷し、行の代わりにバイト数を計算する機能を.使用して点数を計算します。wcwc -c

引用する

答え2

GNUを使用してディレクトリ内の各種類のファイル数を再帰的に分析するには、find次のようにします。

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 (&)/'

/usr/bin私のシステムは以下を提供します。

   3727 regular files
    710 symbolic links

存在する/dev

     83 block devices
    203 character devices
     31 directories
    426 symbolic links
      1 FIFOs
      1 Unix domain sockets

シンボリックリンクの場合、シンボリックリンクが指すファイルタイプとして計算されるようにするには、symbolic links次のように変更できます。

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 (&)/'

今これは私に次のことを与えます/usr/bin

      1 directories
   4434 regular files
      2 broken symbolic links

(壊れたシンボリックリンクは、findファイルが存在しない、アクセスできないディレクトリにある、またはファイルパスの検証にサイクルがあるため、タイプが解決できないファイルを指すシンボリックリンクです。私の場合は、次のようになります。リンクがなくなりました。)

これらのどれも.平和とは見なされません..。これを含めたい場合(その理由は何ですか?)、find各ディレクトリに存在すると仮定し、体系的に計算する以外の方法はありません。

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 (&)/'

それから私が与えられました/usr/bin

      2 directories
   3727 regular files
    710 symbolic links

GNUにアクセスできない場合は、find最初のものを次のように書き直すことができます。

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

厳密に言えば、我々は計算しなかった。文書しかし、ディレクトリエントリ。同様のディレクトリには、/usr/bin同じファイルを指す複数のエントリがあることがよくあります。たとえば、ここにあります。

$ 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

これは、同じファイル(inode 672252を持つファイル)の3つのディレクトリエントリ(ファイル名、ハードリンクとも呼ばれます)です。 GNUfindとGNUを使用してディレクトリエントリの代わりにファイル数を計算します(uniqとにかく他のディレクトリへのハードリンクである.ファイルは無視されます..)。

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 (&)/'

鉱山では/usr/bin以下を提供しています。

   3711 regular files
    710 symbolic links

答え3

/usr/binの下のすべてのファイルを再帰的にしたいのか、それとも最初のレベルだけが欲しいのかは話しませんでした。また、数えることができる単語をどのように取得しますか?それを見つける一般的な方法は、wcでfindを実行することです。次のようになります。Find / usr / bin | wc -l Findは、そこにあるすべてのもの、ディレクトリー、およびファイルをリストします。 Wc -l は find 出力のすべての行数を計算します。これはクラスの課題ですか?だとしたら大丈夫です。しかし、答えをより慎重にカスタマイズできるように、この情報が必要な理由を知りたいです。さらに必要に応じて教えてください。コスタ

答え4

Bashでは外部ツールは必要ありません。

cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"

Bashでは、外部ツールや再帰は必要ありません。

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

関連情報