Bash: знайдіть папки з файлами менше x


7

Як би я міг знайти всі папки в каталозі, ніж містити менше x кількості .flacфайлів?

Відповіді:


9
  • Для кожного підкаталогу надрукуйте ім'я підкаталогу, якщо у підкаталозі є щонайбільше 42 .flacфайли. Для виконання команди в каталогах замініть -printна -exec … \;. POSIX сумісний.

    find . -type d -exec sh -c 'set -- "$0"/*.flac; [ $# -le 42 ]' {} \; -print

    Зауважте, що ця команда не працюватиме для пошуку каталогів, що містять нульові .flacфайли ( "$0/*.flac"розширюється принаймні до одного слова). Натомість використовуйте

    find . -type d -exec sh -c 'set -- "$0"/*.flac; ! [ -e "$1" ]' {} \; -print
  • Той самий алгоритм в zsh. **/*розширюється на всі файли в поточному каталозі, а його підкаталоги рекурсивно. **/*(/)обмежує розширення на каталоги. {.,**/*}(/)додає поточний каталог. Нарешті, (e:…:)обмежує розширення на відповідність, для яких код оболонки повертає 0.

    echo {.,**/*}(/e:'set -- $REPLY/*.flac(N); ((# <= 42))':)

    Це можна розбити в два етапи для розбірливості.

    few_flacs () { set -- $REPLY/*.flac(N); ((# <= 42)); }
    echo {.,**/*}(/+few_flacs)

Журнал змін :
• правильно обробляйте x = 0.


1
Перша команда друкує всі підкаталоги. $#завжди принаймні 1, отже [ $# -le 42 ]вірно, коли flacв підкаталозі немає файлів.
cYrus

@cYrus: Якщо файлів flac немає, є менше 42 файлів flac. Гаразд, я мав би зазначити, що мої рішення працюють лише для 42> 0, тому вони не працюватимуть для пошуку каталогів, що не містять файлів flac (потрібна інша, простіша команда).
Жиль,

Я не говорю про пошук каталогів без flacфайлів (x = 0). Я говорив, що якщо каталог не містить flacфайлів, $#це 1, тому що $1це буквально path-to-dir/*.flac(оскільки немає розширення), каталог все одно надрукується. Це просто інша точка зору, я припускаю, що каталог без flacфайлів не відповідає запиту.
cYrus

2

Замініть $MAXвласним лімітом:

find -name '*.flac' -printf '%h\n' | sort | uniq -c | while read -r n d ; do [ $n -lt $MAX ] && printf '%s\n' "$d" ; done

Примітка. Це надрукує всі підкаталоги з кількістю .flacфайлів між 0та $MAX(обидва виключені).


2
Зробіть так, щоб read -r n dімена каталогів випадків містили зворотні риски, а printf "%s "$d"в іменах каталогів випадків - пробіли або -\['"\\`.
Жиль

Дякую за те -r, що я дуже пропустив це! Але я не можу бачити жодної проблеми з ехою, вона правильно працює з такими каталогами, як: st r \ a \ `n- [g \" e
cYrus

вибачте, неправильний набір спеціальних символів. Я мав би сказати -*?\\[. Спробуйте створити два каталоги під назвою fooі f*, зі f*збігом. Або каталог, який називається foo bar(два пробіли). Або (залежно від вашої оболонки) каталог, який називається -eабо -n.
Жиль,

Каталог під назвою -e... зло!
cYrus

1
Щоб уникнути будь-яких проблем із глобальними підмінами, вам слід скористатися -name '*.flac'.
Крістіан Цюпіту,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.