Как найти все каталоги с более чем x файлами, превышающими указанный размер?

Сzsh:

mood='I am $1 happy'

happy () {
  printf '%s\n' ${(e)mood}
}

happy very

Флаги расширения параметра eвызывают оценку всех расширений параметров, арифметических расширений и подстановок команд в содержимом переменной. (обратная косая черта перед $или `может использоваться для предотвращения их ).

Другой подход, который позволяет избежать опасных вещей, таких как eили eval, заключается в использовании gettextс envsubst, где вы можете точно указать, что вы хотите заменить:

mood='I am $HOWMUCH happy'
happy() {
  HOWMUCH=$1 envsubst <<< "$mood"
}
happy very

Хотя <<<также является расширением zsh, теперь оно поддерживается несколькими другими оболочками, включая bash.

Замените envsubstна envsubst '$HOWMUCH', если вы хотите, чтобы были заменены только$HOWMUCH(или ${HOWMOUCH}).

С помощью ksh93или zshвы также можете использовать:

mood='I am %1$s happy\n'
happy() {
  printf "$mood" "$@"
}

В других реализациях printf, которые не поддерживают %1$s, чтобы указать, какой аргумент использовать, в этом конкретном случае вы можете использовать %s.Если формат имеет %s %s, первый %sполучает первый аргумент, второй — второй аргумент. Вы можете использовать %2$s %1$s, чтобы изменить порядок с помощью ksh93или zsh. В других реализациях вместо этого можно было бы использовать этот прием:

case $(locale language) in
  (*English*) msg="I am in a %s %s%.0s%.0s\n";     mood=mood;;
  (*French*)  msg="Je suis d'une %.0s%s %s%.0s\n"; mood=humeur;;
esac

mood() {
  printf "$msg" "$@" "$@"
}

mood formidable "$mood"

Который будет печатать I'm in a formidable moodдля пользователя, говорящего по-английски -, и Je suis d'une humeur formidableдля пользователя, говорящего по-французски -. Мы передаем аргументы дважды и используем%.0s(строку, усеченную до нулевой ширины ), чтобы отбросить те, которые нам не нужны, чтобы иметь возможность использовать эти аргументы в другом порядке.

0
10.06.2021, 13:37
2 ответа

Благодаря @ Муру команда, лишь слегка измененная,:

find. -type d -exec sh -c '[ $(find "$1" -type f -size +1M | wc -l) -gt 1 ]' _ {} \; -print

В примере выполняется поиск всех папок в текущем каталоге (вы можете заменить точку для полных путей )на 2 или более файлов размером более 1 МБ.

0
28.07.2021, 11:25

Сzsh:

x=42 size=M+1
print -rC1 -- **/*(NFe['()(($#)) $REPLY/*(N.L${size}Y${x}[$x]oN)'])

Будут напечатаны каталоги, содержащие не менее 42 файлов, размер которых строго превышает 1 МБ.

  • **/*:рекурсивная подстановка
  • (...):квалификаторы глобуса
  • N:Nullglob :не жалуйтесь, если совпадений нет
  • F:ограничить файлы типа каталог , которые Full (имеют хотя бы одну запись ).
  • e['code']:отфильтровать файлы, для которых eоценка codeвозвращает значение true.
  • ()(($#)) args:анонимная функция, возвращающая значение true, если количество аргументов не равно -нулю
  • $REPLY:файл (здесь каталог )в настоящее время рассматривается в code.
  • $REPLY/*:файлы там. Замените на $REPLY/**/*, чтобы также учитывать файлы в подкаталогах.
  • .:ограничить до обычными файлами (исключить каталоги, символические ссылки, FIFO, устройства... ).
  • LM+1:ограничения на файлы, размер которых, округленный до следующего целого числа мегабайт, строго больше 1 (файлы размером 1048577 байт и выше ).
  • Y$x:перестали смотреть после того, как xй был найден в качестве оптимизации.
  • [$x]:снова выберите xth в этом списке (в качестве оптимизации,поэтому codeнужно только проверить, передан ли хотя бы один аргумент ).
  • oN:не утруждайте себя сортировкой этого списка.

Вы можете добавить квалификатор Dк одному или обоим шаблонам, если вы также хотите учитывать скрытые каталоги/файлы.

Но если вам нужно что-то сделать с этими файлами впоследствии, вы, вероятно, захотите сделать что-то вроде:

for dir in **/*(NF); do
  large_files=($dir/*(N.LM+1))
  (( $#large_files >= 42 )) && do-something-with $large_files
done
3
28.07.2021, 11:25

Теги

Похожие вопросы