2013-06-24 5 views
2

Я пытаюсь распечатать вывод sar, исключая заголовок с именем хоста и датой. Следующая команда не может исключить строки заголовка и вывода разделитель полей тоже:Awk выражение поиска и OFS

sar -u|head -5|awk -F ' 
    BEGIN { hname="'"`hostname -s`"'"; hdt="'"`date +"%d-%b-%Y" `"'" ; OFS="," ;} 
    { $1 ~ /[0-9]/ && $4 ~ /[0-9]/ } 
    { printf("h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9);}' 

но когда используют тот же поиск ехр это хорошо работает!

ответ

0

Вот что вам нужно сделать:

$ hname=$(hostname -s) 
$ hdt=$(date +"%d-%b-%Y") 
$ $ sar -u | awk '$1~/[0-9]/&&$4~/[0-9]/&&NR<=5{print host,dat,$1,$2,$3,$4,$5,$6,$7,$8,$9}' OFS="," host="$hname" dat="$hdt" 

Некоторые указатели:

  • Нет необходимости head, вы можете контролировать количество строк с помощью NR переменной
  • Чтобы использовать bash в awk вам нужно использовать system() или вы можете хранить команды bash в переменной и называть их в awk, как мы сделали выше.
  • переменныхOFS и ORS сепаратор выходных не оказывает никакого влияния на printf заявлении
+0

Спасибо за предложение. – Vinod

+0

Спасибо за предложение. - Я использовал ** head ** временно, просто чтобы проверить несколько строк. Позже он будет удален. Спасибо, что напомнил мне переменную NR. - Я пытаюсь использовать system() в awk, но он возвращает 0 (успешный код) в результате, а не фактический вывод. - Мне нужен printf bcoz выхода с фиксированным форматом - Моя главная проблема - поиск, почему мой поиск не работает? – Vinod

1

Попробуйте следующий код:

sar -u|head -5|awk ' 
    BEGIN { hname="'"`hostname -s`"'"; hdt="'"`date +"%d-%b-%Y" `"'" ; OFS="," ;} 
    $1 ~ /[0-9]/ && $4 ~ /[0-9]/ 
    { printf("h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9);}' 

Заметьте, что это не тестировалось, так как у меня нет программы sar установлен. Если вы вставляете какой-то пример вывода этой программы, я могу проверить код и соответственно обновить свой ответ.

Это как можно ближе к вашему коду и должно работать, если я не пропустил ничего другого. Используемый вами вариант -F ничего не сделал, поскольку вы не указали новый разделитель полей (FS). Обратите внимание, что я снял фигурные скобки (фигурные скобки, {...}) вокруг вашего «поиск» заявление $1 ~ /[0-9]/ && $4 ~ /[0-9]/.

awk программа состоит из шаблонов и связанных действий, которые выполняются для тех записей (без дополнительных опций, каждая строка считается одним записью) сопоставлениями шаблона. Действие должно быть заключено в фигурные скобки после соответствующего рисунка .

Так что ваш код имеет три действий: Инициализация, что связанно с особым НАЧАТЬ рисунок и, таким образом, выполняется один раз перед чтением каких-либо входное и два действий, которые выполняются для всех записей (т.е. линии) поскольку они не связаны ни с одним шаблоном .: первое оценивает ваше выражение поиска, а второе печатает отформатированную запись .Обратите внимание, однако, что эти два действия : не связан, и действие печати выполняется независимо от того, было ли ваше выражение поиска оценено как true или false.

Чтобы понять, что случилось с вашим кодом вы можете запустить этот многословный вариант:

sar -u|head -5|awk ' 
    BEGIN { hname="'"`hostname -s`"'"; hdt="'"`date +"%d-%b-%Y" `"'" ; OFS="," ;} 
    {print "search returned "($1 ~ /[0-9]/ && $4 ~ /[0-9]/?"true.":"false.")} 
    { printf("h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9);}' 

Это расширяет свое первое действие напечатать результат вашего выражения поиска, и вы увидите, что второй (т.е. printf) Действие выполнено независимо от этого результата.

Удаляя скобки вокруг выражения поиска, вы делаете что узор связан со следующим действием, то printf один. Таким образом, printf выполняется только для тех записей (т. Е. Линий), соответствующих вашему запросу pattern.

Далее отметим, что ваш код становится более читаемым, если вы сохраняете вывод Внешним команд в переменных as suggested по @jaypal singh, в дальнейшем достигается путем инициализации awk переменных с помощью -v опции:

sar -u|head -5|awk \ 
       -v hname="`hostname -s`" \ 
       -v hdt="`date +"%d-%b-%Y"`" \ 
       -v OFS="," \ 
       ' 
       $1 ~ /[0-9]/ && $4 ~ /[0-9]/{ 
       printf("h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9) 
       } 
       ' 

Добавление:

As pointed out от @jaypal singh, то выходной разделитель полей (OFS) не повлияет на prinft, поэтому вы можете использовать запятую (,) вместо пространства () в вашем printf заявления вместо определения OFS:

sar -u|awk \ 
     -v hname="`hostname -s`" \ 
     -v hdt="`date +"%d-%b-%Y"`" \ 
     ' 
     $1 ~ /[0-9]/ && $4 ~ /[0-9]/{ 
     printf("h=%-15s,d=%11s,1=%8s,2=%2s,3=%-3s,4=%6.2f,5=%6.2f,6=%6.2f,7=%6.2f,8=%6.2f,9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9) 
     } 
     ' 

Обратите внимание, что на этот раз я также удалил head из трубопровода, так как вы указали в комментарии, что это только что было введено по причинам тестирования, и если бы он не использовал номер записи (NR), было бы лучше as suggested от @jaypal singh.