С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
(строку, усеченную до нулевой ширины ), чтобы отбросить те, которые нам не нужны, чтобы иметь возможность использовать эти аргументы в другом порядке.
Благодаря @ Муру команда, лишь слегка измененная,:
find. -type d -exec sh -c '[ $(find "$1" -type f -size +1M | wc -l) -gt 1 ]' _ {} \; -print
В примере выполняется поиск всех папок в текущем каталоге (вы можете заменить точку для полных путей )на 2 или более файлов размером более 1 МБ.
Сzsh
:
x=42 size=M+1
print -rC1 -- **/*(NFe['()(($#)) $REPLY/*(N.L${size}Y${x}[$x]oN)'])
Будут напечатаны каталоги, содержащие не менее 42 файлов, размер которых строго превышает 1 МБ.
**/*
:рекурсивная подстановка (...)
:квалификаторы глобуса N
:N
ullglob :не жалуйтесь, если совпадений нет F
:ограничить файлы типа каталог , которые F
ull (имеют хотя бы одну запись ). 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