Як я можу використовувати счетчик слів ( wc
) та трубопроводів, щоб підрахувати, скільки файлів чи каталогів є в /usr/bin
каталозі?
Як я можу використовувати счетчик слів ( wc
) та трубопроводів, щоб підрахувати, скільки файлів чи каталогів є в /usr/bin
каталозі?
Відповіді:
Одним із підходів було б скористатися для того, ls
щоб надати нам список файлів, але ми хочемо, щоб у цьому списку було відображено лише 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
«s -c
варіанти:
$ ls -l | grep -c '^d'
(знову ж таки, приховані файли не включаються. Зауважте, що каталоги та регулярні файли - це два типи. Є ще багато таких як названі труби, символічні посилання, пристрої, розетки ...).
Якщо вам потрібно знайти файли та каталоги рекурсивно, /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
вважає каталоги та файли, що містять нові рядки, як 2 елементи, а не один.
$ ls -1 | wc -l
10
Один із способів подолати це, якщо використовується реалізація GNU, - find
це використовувати find
здатність друкувати щось інше замість кожного знайденого файлу, а потім замість них рахувати.
$ find . -printf . | wc -c
9
Тут ми знаходимо все в поточному каталозі ( за винятком ..
), і друк точка ( .
) для кожного, а потім підрахунок точок , використовуючи wc
здатність «s для підрахунку байт замість рядків, wc -c
.
/usr/bin
будуть добре відформатовані (а також не містять пробілів, з технічної точки зору, ви могли б навіть просто echo * | wc -w
), варто зазначити, що всі вони будуть розбиті на назви файлів, що містять нові рядки.
ls -l
чи ls -1
/ ми будемо рахувати рядки, а не слова! find
Може зламатися, але знову ж , ми розраховуємо рядки не слово.
touch $'foo\nbar'
у порожньому каталозі, за яким слідує одна з ваших команд (скажімо ls -1 | wc -l
), буде повідомлено два файли, а не один - тому що цей файл - це два рядки, наскільки wc
це стосується. Якщо тільки не ls
замінює нові рядки якимось іншим символом (я не думаю, що це робить, але я знову не в змозі перевірити зараз).
wc -c
проблема під час підрахунку періодів?
Якщо ви хочете отримати кількість даних про файл кожного типу рекурсивно під деяким режимом, за допомогою 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
не можна визначити тип, тому що файл не існує, або знаходиться в каталозі, до якого ви не маєте доступу, або є петля в роздільній здатності файлу. . У моєму випадку, ті 2, де посилаються на файли, яких тепер немає).
Ніхто з них не рахує .
і ..
. Якщо ви хотіли, щоб вони були включені (чому б вам це зробити?), Немає іншого способу, 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
Це 3 записи каталогів (імена файлів ака ж жорсткі посилання) на той самий файл (той, який має inode 672252. Для підрахунку файлів замість записів каталогів та з GNU find
та 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
Ви ще не говорили, чи хочете, щоб весь файл під / usr / bin був рекурсивно або просто під першим рівнем. Крім того, як ви збираєтеся отримати слова, які ви рахуєте? Звичайний спосіб з'ясувати це запустити пошук у туалет. Ось так: знайти / usr / bin | wc -l Find перерахує все там, каталоги та файли. Wc -l буде рахувати всі рядки у знаходженні результатів. Це завдання для класу? Це нормально, якщо це так, але мені було цікаво, навіщо вам потрібна ця інформація, щоб я міг більш ретельно адаптувати відповідь. Будь ласка, дайте мені знати, якщо вам потрібно більше. Коста
Баш, без зовнішніх інструментів.
cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"
Баш, без зовнішніх інструментів та рекурсії.
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
.
ані ..
записи. Ви можете роз’єднати файл проти звичайного файлу.