В ответе Майкла отсутствует одна вещь :очистка удаляет только архивные файлы журналов, а не активные. Чтобы избавиться от всего, вам нужно сначала повернуть файлы, чтобы последние записи были перемещены в неактивные файлы.
Таким образом, полный ответ на удаление всех записей выглядит так:
sudo journalctl --rotate
sudo journalctl --vacuum-time=1s
(Обратите внимание, что вы не можете объединить это в одну команду journalctl
.)
Кстати, в некоторых дистрибутивах journald настроен так, что он записывает логи на диск (/var/log/journal
), а другие хранят логи в памяти(/run/log/journal
).Я ожидаю, что в некоторых случаях может быть необходимо сначала использовать sudo journalctl --flush
, чтобы удалить все.
Если в вашей версии нет --rotate
, вы можете использовать аргумент --since
для фильтрации записей:
--since "2019-01-30 14:00:00"
--since today
Вы можете перебрать каждый каталог по очереди, подсчитать количество содержащихся в нем файлов, а затем переместить его... куда-нибудь. Например,
for dir in./*/
do
count=$(find "$dir" -maxdepth 1 -type f -printf "x\n" | wc -l) # Count the number of files in this subdirectory
[ $count -gt 100 ] && echo mv "$dir" # Output a message if we have enough
done
Вы можете ввести это прямо в подсказке (, вы получите дополнительную подсказку, >
, после первой строки до последней )или сохраните ее в файле сценария и запустите.
Чтобы подсчитать количество не -скрытых имен в каталоге dir
, вы можете использовать
set -- dir/*
Это расширяет глобус *
в каталоге и устанавливает позиционные параметры для результирующих имен. Если шаблон совпал с чем-либо , счет будет в $#
.
Чтобы выполнить итерацию по всем каталогам в некотором каталоге верхнего -уровня top-dir
, подсчитайте количество имен в каждом и сделайте что-нибудь с каталогами, которые содержат более 100 имен:
for subdir in top-dir/*/; do
set -- "$subdir"/*
if [ -e "$1" ] && [ "$#" -gt 100 ]; then
# do something to "$subdir"
fi
done
В оболочке bash
установка параметра оболочки nullglob
избавляет от необходимости проверять, удалось ли команде set
сопоставить какие-либо имена вообще (, поскольку шаблон был бы полностью удален, если бы нет совпадений вместо того, чтобы оставаться нераскрытым ).
shopt -s nullglob
for subdir in top-dir/*/; do
set -- "$subdir"/*
if [[ $# -gt 100 ]]; then
# do something to "$subdir"
fi
done
Дополнительная установка параметра оболочки dotglob
приведет к тому, что каждый шаблон в коде также будет соответствовать скрытым именам.
В любом фрагменте кода выше комментарий «сделайте что-нибудь с "$subdir"
» можно заменить на все, что вам нужно сделать с этими подкаталогами. Например,. уберите их, используйте
mv "$subdir" some/other/dir
Что переместит их в каталог some/other/dir
.
Сzsh
:
mv -- *(/Fe['()(($# > 100)) $REPLY/*(N^-/)']) /dest/
Будет перемещен в /dest/
не -скрытые подкаталоги текущего рабочего каталога, которые содержат более 100 записей¹, которые не являются ни скрытыми, ни типом каталога (, который, как я предполагаю, вы подразумеваете под файлом).
При этом используются квалификаторыzsh
glob((/Fe...)
и (N...)
выше ), которые дополнительно выбирают подходящие файлы на основе других критериев, а не их имени.
/
:выберите только файлы типа из каталога . Здесь (в отличие от */
glob )тип определяется до разрешения символической ссылки, что, вероятно, здесь предпочтительнее, поскольку перемещение символических ссылок часто их ломает ).F
:выбирает полные файлы в качестве оптимизации (для каталогов, что означает непустые каталоги)e[code]
:выбрать на основе результата интерпретации code
, где $REPLY
содержит рассматриваемый в данный момент файл. Это code
здесь ()(($# > 100)) $REPLY/*(N^-/)
.
() <body> <args>
— встроенная функция. Здесь тело((($# > 100))
)проверяет, что количество аргументов больше 100. Аргументы являются расширением глобуса $REPLY/*(N^-/)
снова с использованием квалификаторов глобуса :
N
:nullglob :этот глобус будет расширяться до вообще без аргумента вместо ошибки, когда нет соответствующего файла. ^
:отрицает следующие квалификаторы. -/
аналогичен /
выше, за исключением того, что -
заставляет следующие квалификаторы (здесь/
)применять после разрешения символической ссылки . Итак, здесь мы подсчитываем файлы, которые имеют не типа каталог после разрешения символической ссылки. Вы можете заменить ^-/
на .
, чтобы считать только обычные файлы (, исключая все другие типы файлов, такие как сокеты, fifo, каталоги, символические ссылки... ), или -.
для обычных файлов и символических ссылок на обычные файлы. Чтобы также учитывать скрытые каталоги/файлы, добавьте квалификатор D
(к одному или обоим внешнему и внутреннему шаблонам ).
Чтобы также рекурсивно подсчитывать файлы в подкаталогах, замените второй *
на**/*
(или ***/*
для обхода символических ссылок при спуске по дереву каталогов ).
Вы можете оптимизировать его, изменив code
на:
()(($#)) $REPLY/*(NoN^-/[101])
Это использование oN
для отключения сортировки файлов, порядок которых нам не важен, а глобус расширяется только до 101 st соответствующего файла, который мы просто проверяем на присутствие с помощью(($#))
(количество аргументов не -ноль ).
¹ Остерегайтесь, что несколько записей могут ссылаться на один и тот же файл, например, когда они соединены жесткими или символическими ссылками. Подсчет количества уникальных файлов будет другим упражнением
Мы формируем цепочку проверок для определения действительного файла в каталоге без символической ссылки. каталоги могут быть скрыты или нет, файлы могут быть скрыты или нет.
Изменить количество файлов в пороговой переменной и путь назначения в папке назначения _Переменная. Удалите эхо, как только все будет в порядке.
Исправлена ошибка, из-за которой тест каталога с символической ссылкой завершался ошибкой для имени с косой чертой в конце и командой mv, как указал Стивен.
$ threshold=100
$ dest_dir=final/resting/place
$ for d in./*/./..?*/./.[!.]*/; do
[ ! -L "${d%/}" ] && [ -d "$d" ] && \
[ "$(cd "$d" && find.//. ! -name. -prune -type f | grep -cF.//.)" -gt "$threshold" ] \
&& echo mv -- "$d" "$dest_dir";
done
Мы можем свести к минимуму количество перемещений, если будем использовать xargs GNU, которые ограничивают аргументы NUL \0
char, и последние версии mv, которые поддерживают -параметр t (target dir):
$ threshold=100
$ dest_dir=final/resting/place
$ for d in./*/./..?*/./.[!.]*/; do
[ ! -L "${d%/}" ] && [ -d "$d" ] && \
[ "$(cd "$d" && find.//. ! -name. -prune -type f | grep -cF.//.)" -gt "$threshold" ] \
&& printf '%s\0' "$d"
done | xargs -r0 -t mv -t "$dest_dir"
Помимо подходов к оболочке, вы также можете использовать конвейер, состоящий из find
команды, созданной для выбора папок/файлов для проверки и передачи их сценарию Awk, который выполняет фильтрацию для окончательного xargs
, который объединяет фактический mv
за минимально возможное количество запусков. Это также может быть сценарий оболочки, но Awk обычно лучше и быстрее обрабатывает текст.
В приведенном ниже примере используются инструменты GNU, предназначенные для работы с nul -вводом-выводом с разделителями, чтобы поддерживать имена файлов со встроенными символами новой строки:
find. -maxdepth 2 \( -regex '^./[^/]+' -o -type f \) ! -name '.*' -print0 \
| LC_ALL=C gawk -F/ -v RS='\0' -v ORS='\0' \
'{if (NF==2) {d=1; n=0} else if (d && ++n>100) {d=0; print $2}}' \
| xargs -r0 mv -t dest/
По сравнению с решениями на основе чистой оболочки этот конвейер должен быть менее требовательным к ресурсам, поскольку он не выполняет никакой буферизации во время обработки, поэтому на него практически не влияет любое количество папок и файлов.
Обратите внимание на сравнение n>100
в скрипте awk
:, где вы можете настроить порог по желанию.
Ожидается, что этот конвейер будет запускаться из каталога, содержащего папки для проверки, поскольку он использует «голый» find.
. Тем не менее, вы можете легко сделать его общим, просто добавив часть find.
к части cd -- "${topdir:-.}" &&
, чтобы указать начальный каталог с помощью пользовательской переменной оболочки $topdir
, по умолчанию равной .
, то есть текущему каталогу.
Справедливый эквивалент такого конвейера с использованием инструментов BSD, за исключением поддержки новых строк в именах файлов из-за ограничений, присущих инструментам BSD, может быть следующим:
find -E. -maxdepth 2 \( -regex '^./[^/]+' -o -type f \) ! -name '.*' \
| LC_ALL=C awk -F/ -v q=\' \
'{if (NF==2) {d=1; n=0} else if (d && ++n>100) {d=0; gsub(q, q"\\"q q, $2); print q$2q}}' \
| xargs sh -c '${1:+mv -- "$@" dest/}' --
, который по сути такой же, как версия инструментов GNU, за исключением различных опций -print0
, -z
и -0
, а также дополнительной операции gsub()
сценария awk
для кавычек разделительных символов (символы " ' <space>
), возможно, присутствующие в именах файлов, как это необходимо POSIX xargs
для использования.
Этот последний конвейер должен корректно работать в любой системе BSD, при условии, что ни один проверяемый путь (к папкам и файлам )не содержит новых строк.
Говоря о совместимости с POSIX,конвейер инструментов BSD также должен работать в любой системе POSIX, за исключением команды find
, поскольку в POSIX нет предложений -maxdepth
и -regex
. Эквивалент POSIX для этого find
может быть похож на:
# replace the find command of the BSD tools version, up to and including the trailing backslash character
find. \( -path '*/*/*' ! -path '*/*/*/*' -type f \) -o \( -path '*/*' ! -path '*/*/*' -type d \) ! -name '.*' \
Выражение find
также создано для облегчения работы сценария awk
и выбирает обычные файлы на третьем уровне иерархии каталогов (, где уровень 1 равен .
), плюс только каталоги на втором уровне. Не имея более мощных предложений, доступных в BSD и GNU find
, я получаю тот же результат, играя в предложения -path
.
Наконец, обратите внимание, что эти конвейеры явно игнорируют скрытые файлы через предложение ! -name '.*'
до find
, и они рассматривают только обычные файлы через предложение -type f
(, следовательно, исключая, например,. символические ссылки ), потому что это казалось наиболее разумным выбором в соответствии с вашим вопросом, но если вы хотите учитывать скрытые файлы и/или вложенные -папки, символические ссылки и, возможно, специальные файлы (именованные каналы, именованные сокеты, и т. д. ), которые могут присутствовать внутри папок, вы можете просто убрать соответствующее предложение или, возможно, настроить их с помощью дополнительных предложений для команды find
. В этом последнем случае обратите внимание на то, чтобы заставить find
всегда выдавать имена одиночных папок 1 , потому что эти одиночные имена являются «сигналом», используемым сценарием awk
для определения того, что следующие имена в папке, отличной от предыдущих имен 2 .
1. только те, что на втором уровне
2. для лучшей производительности я использовал проверку истинности/ложности вместо сравнения строк, см. переменную d
в скрипте awk