ディレクトリにどれだけのファイルやディレクトリがあるかを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
ここでは、現在のディレクトリ内のすべての項目(除外..
)を検索し、それぞれについて点()を印刷し、行の代わりにバイト数を計算する機能を.
使用して点数を計算します。wc
wc -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