Чтобы подсчитать точное количество ошибок, которые rm
производит:
find "$CDIR" -depth -mtime +7 -exec sh -c '
for pathname do
if ! rm -rfv "$pathname"; then
count=$(( count + 1 ))
fi
done
printf "This batch caused %d errors in rm\n" "$count"' sh {} +
Это выполнит глубокий -первый поиск в $CDIR
и его подкаталогах -и удалит любой файл или каталог с отметкой времени модификации более недели назад. Сценарий оболочки в строке -будет вызываться для пакетов найденных путей, и он выполняет итерацию по каждому, пытаясь удалить его с помощью rm
. Если удаление не удалось, оно засчитывается. В конце сценария строки -сообщается количество сбоев для этой партии.
Обратите внимание, что это очень небезопасный способ очистки, так как вся структура каталогов с корнем $CDIR
будет удалена, если ни один файл или каталог в самом $CDIR
не был добавлен или удален в течение нескольких недель. время . Та же проблема верна для каждого подкаталога $CDIR
.
Вместо этого вы можете удалить только старые файлы , а затем удалить пустые каталоги по отдельности:
find "$CDIR" ! -type d -mtime +7 -exec sh -c '
for pathname do
if ! rm -fv "$pathname"; then
count=$(( count + 1 ))
fi
done
printf "%d files in this batch could not be deleted\n" "$count"' sh {} +
find "$CDIR" -type d -empty -delete
(Это предполагает, что у вас есть реализация find
, которая поддерживает -empty
и -delete
, и что вы согласны с удалением пустых каталогов, даже если они не были очищены первой командой find
)
Как всегда, при тестировании команд, выполняющих подобные очистки, запускайте копии данных и сохраняйте резервную копию данных.
Другой (более простой )подход заключается в простом удалении старых файлов, а затем подсчете количества старых вещей, которые все еще существуют. Это число будет равно количеству раз rm
сбоев (, хотя я использую здесь -delete
для краткости ):
find "$CDIR" ! -type d -mtime +7 -delete
find "$CDIR" ! -type d -mtime +7 -exec echo x \; | wc -l
Затем вы также можете очистить пустые каталоги, как описано выше.
Всякий раз, когда вы обнаруживаете, что используете $'{...}'
вокруг awk-скрипта, вы делаете что-то не так и должны обратиться за помощью. Никогда не делайте этого, так как это никогда не требуется в хорошо -написанном сценарии и делает ваш сценарий уязвимым, поскольку он предлагает оболочке интерпретировать некоторые его части еще до того, как awk их увидит.
Вы избегаете метасимволов регулярных выражений, чтобы регулярное выражение действовало как строка. Не делайте этого -просто используйте строку вместо операторов регулярных выражений, когда вы хотите сопоставить строку:
awk 'index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
\047
вместо '
, потому что вы не можете экранировать '
в строке с разделителями'
-(, включая скрипты )в оболочке. См. http://awk.freeshell.org/PrintASingleQuote.
Чтобы выделить 2 разные линии одним цветом, вы можете использовать:
awk '
index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") ||
index($0,"DEBUG StateMachine|exit \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
и выделить 2 строки двумя разными цветами:
awk '
index($0,"DEBUG StateMachine|entr \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;42m" $0 "\033[0m"
}
index($0,"DEBUG StateMachine|exit \047NTP:nextGetTimeTimeoutState\047") {
$0 = "\033[1;41m" $0 "\033[0m"
}
1' LOG.log
Сказав это, поскольку вы, очевидно, пытаетесь использовать разные цвета на основе разных частей ввода, теперь было бы уместно использовать регулярное выражение с группами захвата, чтобы изолировать соответствующие части ввода, а затем просто посмотреть на эти части. части, чтобы определить цвет, который будет использоваться для каждой строки, и вот как я бы реализовал это, используя GNU awk для третьего аргумента, чтобы соответствовать ()для групп захвата:
$ cat tst.awk
BEGIN {
red = "\033[1;41m"
green = "\033[1;42m"
yellow = "\033[1;43m"
blue = "\033[1;44m"
purple = "\033[1;45m"
reset = "\033[0m"
map["nextGetTimeTimeoutState","entr"] = green
map["nextGetTimeTimeoutState","exit"] = red
map["nextIteratorState","entr"] = yellow
map["nextIteratorState","task"] = blue
map["nextIteratorState","exit"] = purple
}
match($0,/(DEBUG|INFO) StateMachine\|(\S+)\s+\047NTP:([^\047]+)\047/,a) {
key = a[3] SUBSEP a[2]
if ( key in map ) {
$0 = map[key] $0 reset
}
}
{ print }
или используя любой POSIX awk:
$ cat tst.awk
BEGIN {
red = "\033[1;41m"
green = "\033[1;42m"
yellow = "\033[1;43m"
blue = "\033[1;44m"
purple = "\033[1;45m"
reset = "\033[0m"
map["nextGetTimeTimeoutState","entr"] = green
map["nextGetTimeTimeoutState","exit"] = red
map["nextIteratorState","entr"] = yellow
map["nextIteratorState","task"] = blue
map["nextIteratorState","exit"] = purple
}
match($0,/(DEBUG|INFO) StateMachine\|[^[:space:]]+[[:space:]]+\047NTP:[^\047]+\047/) {
split($0,a,/[|[:space:]:\047]+/)
key = a[9] SUBSEP a[7]
if ( key in map ) {
$0 = map[key] $0 reset
}
}
{ print }
Какой бы из них вы ни использовали, вывод будет:
Вам не нужны промежуточные переменные red
, green
и т. д., как можно было бы просто:
map["nextGetTimeTimeoutState"]["entr"] = "\033[1;42m"
map["nextGetTimeTimeoutState"]["exit"] = "\033[1;41m"
, но я считаю, что они помогают ясности и упрощают дальнейшее обслуживание/обновления.
Если я вас правильно понял, вы можете использовать регулярное выражение и восьмеричное представление одинарных кавычек(\047)
вот так:
awk '{ sub(/^.*DEBUG StateMachine\|entr \047NTP:nextGetTimeTimeoutState\047/, "\033[1;41m&\033[0m/); print }' LOG.log
Что касается других методов , существуют такие пакеты, как colorize
илиccze
где вы можете ввести в них некоторый текст, и они -значительно улучшат ваш вывод. В большинстве случаев используется общий цветовой профиль -, но можно написать и свой собственный.
Сначала попробуйте значения по умолчанию и посмотрите, понравится ли вам это.
Так как это прямолинейное «внесение правок в несколько совпадающих строк», вам не нужны возможности awk. Как уже отмечали другие, большая часть вашей проблемы заключается в правильном цитировании.
Использование sed в одной строке
sed "/DEBUG StateMachine|entr 'NTP:nextGetTimeTimeoutState'/s/.*/"$'\e[[1;41m&\e[0m'/
или в 3
PAT=" DEBUG StateMachine|entr 'NTP:nextGetTimeTimeoutState'"
TO=$'\e[[1;41m&\e[0m'
sed "/$PAT/s/.*/$TO/"