Как удалить последние две строки вывода используя 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 #############################

Если ничего не работает

... | sed '$d' | sed '$d'

Выйдите из awk, чтобы поработать над математикой

awk '{if (NR > 2 && NR < '$(( $(wc -l <$file) -1))')print $0}' $file

Если номер записи больше 2, мы пропустили первые 2 строки. Если это меньше, чем общее количество строк минус 1, мы остановились раньше двух последних (вы можете использовать -2, если вы используете <=).

Другие вопросы по тегам