Как удалить последние две строки вывода используя AWK?
Я пытаюсь сделать графическое представление вывода, который показывает свободную память сервера текущего дня (который отображается приблизительно в часах), из этого вывода я не хочу первые две строки и последние две, первые две я Я могу легко удалить с помощью NR, хотя у меня были проблемы с последними двумя, единственный найденный мной способ - стереть весь вывод, удалить первые две строки, а затем снова вернуть его в нормальное состояние.
Есть ли лучший / правильный способ удалить последние две строки, но сделать это внутри AWK?
это то, что я до сих пор и работает отлично.
echo 'graphics (freemem)'
echo 'GiB 0 500k 1M 1,5M'
sar -r | tail -r | awk 'NR > 2{ print }' | tail -r | nawk '
NR > 4{
LINE = sprintf("%" int(($2 / 100000)*2 )"s", " ");
gsub(/ /, "#", LINE);
print $1, LINE; }
'
ОБНОВИТЬ
Поэтому я сделал это по-другому, потому что это облегчит чтение сценария, и он будет работать для меня, но для любого другого парня, которому необходимо это сделать, используйте либо предыдущий способ, которым я это сделал, либо способы, которые ответили парни ниже.
echo 'graphics (freemem)'
echo 'GiB 0 500k 1M 1,5M'
sar -r | nawk '
NR > 4 && $1 !~ /Average/ && $1 !~ /^$/ {
LINE = sprintf("%" int(($2 * 2) / 100000 )"s", " ");
gsub(/ /, "#", LINE);
print $1, LINE; }
'
ОБНОВЛЕНИЕ 2
Поэтому я хочу сделать графическое представление отслеживаемых данных, эти выходные данные обновляются примерно каждый час, имейте в виду, что в разные часы дня длина строк варьируется. Так что это фактический выход sar -r
что я получаю.
.
SunOS doc 5.10
00:00:00 freemem freeswap
01:00:01 1624430 19474799
02:00:00 1624421 19474738
03:00:00 1624413 19474683
04:00:00 1624527 19475309
05:00:00 1624525 19475290
06:00:00 1624517 19475232
07:00:01 1624510 19475176
08:00:00 1624503 19475120
08:20:00 1539793 18771472
08:40:00 1509924 18535201
09:00:00 1500681 18492050
09:20:00 1494254 18435535
09:40:00 1479623 18266664
10:00:00 1486372 18317241
10:20:00 1480565 18269032
10:40:00 1479030 18260247
11:00:01 1476462 18237731
11:20:00 1475999 18234221
11:40:00 1478854 18259827
12:00:00 1478223 18254861
12:20:00 1482956 18294572
12:40:00 1479061 18260565
13:00:00 1470463 18185441
13:20:00 1474090 18217961
13:40:00 1478585 18257393
14:00:00 1478219 18255445
14:20:00 1474327 18223749
14:40:00 1470468 18190676
15:00:00 1471941 18204282
15:20:00 1474138 18223380
15:40:00 1471698 18202561
16:00:00 1470316 18191099
16:20:00 1467203 18163653
16:40:00 1468943 18179148
Average 1549994 18855701
Таким образом, мы не заботимся о свободе обмена и не используем это. Мы заботимся только о результатах freemem. Итак, что я пытаюсь сделать, это взять в качестве записи этот столбец и "перевести" число в " # " посредством вычисления, чтобы позже я мог указать количество данных в графическом представлении. Хотя в начале и в конце вывода есть строки, которые мне не нужны, поэтому мне нужно, чтобы они были удалены.
Это рабочий код у меня сейчас
echo '\ngraphics (freemem)'
echo 'GiB 0 500k 1M 1,5M'
sar -r | awk 'NR > 2 {print P2} {P2=P; P=$0}' |
nawk '
NR > 4 {
LINE = sprintf("%" int(($2 * 2) / 100000 )"s", " ");
gsub(/ /, "#", LINE);
print $1, LINE; }
'
так что правильный вывод такой:
graphics (freemem)
GiB 0 500k 1M 1,5M
01:00:01 ################################
02:00:00 ################################
03:00:00 ################################
04:00:00 ################################
05:00:00 ################################
06:00:00 ################################
07:00:01 ################################
08:00:00 ################################
08:20:00 ##############################
08:40:00 ##############################
09:00:00 ##############################
09:20:00 #############################
09:40:00 #############################
10:00:00 #############################
10:20:00 #############################
10:40:00 #############################
11:00:01 #############################
11:20:00 #############################
11:40:00 #############################
12:00:00 #############################
12:20:00 #############################
12:40:00 #############################
13:00:00 #############################
13:20:00 #############################
13:40:00 #############################
14:00:00 #############################
14:20:00 #############################
14:40:00 #############################
15:00:00 #############################
15:20:00 #############################
15:40:00 #############################
16:00:00 #############################
16:20:00 #############################
4 ответа
Вы можете сохранить строку, сделать что-нибудь и распечатать через некоторое время, чтобы вы знали, находитесь ли вы в последней строке или нет. Но это слишком много, когда у вас есть такие инструменты, как head
а также tail
,
Просто передайте вывод head
прежде чем передать его awk
:
head -n -2
Тестовое задание
$ seq 10
1
2
3
4
5
6
7
8
9
10
$ seq 10 | head -n -2
1
2
3
4
5
6
7
8
Поскольку у вас нет головы GNU, позволяющей вам это делать, вы можете хранить переменные с помощью awk
:
awk '{if (prev_prev_line) print prev_prev_line; prev_prev_line=prev_line}
{prev_line=$0}'
Это сдвигает линии, так что у вас есть в prev_prev_line
содержание строки у вас было две строки назад:
NR $0 prev_line prev_prev_line
1 1 - -
2 2 1 -
3 3 2 1
4 4 3 2
....
NR-1 NR-1 NR-2 NR-3
NR NR NR-1 NR-2
Так как вы работаете с prev_prev_line
, вы закончите обработку с 1-го по (NR-2)
Строка
Так в prev_prev_line
у вас есть линия, которая произошла две линии назад. Таким образом, вы не используете последние две строки в выводе.
Посмотрите, как это работает на примере:
$ awk '{if (prev_prev_line) print NR,prev_prev_line; prev_prev_line=prev_line}
{prev_line=$0}' < <(seq 10)
3 1
4 2
5 3
6 4
7 5
8 6
9 7
10 8
$ seq 5 | awk 'NR>2{print p2} {p2=p; p=$0}'
1
2
3
Учитывая ваш отредактированный вопрос:
$ cat tst.awk
BEGIN {
print "\ngraphics (freemem)"
print "GiB 0 500k 1M 1,5M"
}
/^[0-9: ]+$/ {
line = sprintf("%*s", int(($2*2)/100000), "")
gsub(/ /,"#",line)
print $1, line
}
,
$ awk -f tst.awk file
graphics (freemem)
GiB 0 500k 1M 1,5M
01:00:01 ################################
02:00:00 ################################
03:00:00 ################################
04:00:00 ################################
05:00:00 ################################
06:00:00 ################################
07:00:01 ################################
08:00:00 ################################
08:20:00 ##############################
08:40:00 ##############################
09:00:00 ##############################
09:20:00 #############################
09:40:00 #############################
10:00:00 #############################
10:20:00 #############################
10:40:00 #############################
11:00:01 #############################
11:20:00 #############################
11:40:00 #############################
12:00:00 #############################
12:20:00 #############################
12:40:00 #############################
13:00:00 #############################
13:20:00 #############################
13:40:00 #############################
14:00:00 #############################
14:20:00 #############################
14:40:00 #############################
15:00:00 #############################
15:20:00 #############################
15:40:00 #############################
16:00:00 #############################
16:20:00 #############################
16:40:00 #############################
Выйдите из awk, чтобы поработать над математикой
awk '{if (NR > 2 && NR < '$(( $(wc -l <$file) -1))')print $0}' $file
Если номер записи больше 2, мы пропустили первые 2 строки. Если это меньше, чем общее количество строк минус 1, мы остановились раньше двух последних (вы можете использовать -2, если вы используете <=).