Разбирать `uptime` только на время

Поскольку нужное вам значение находится в третьем столбце первой строки файла2, вы можете получить его с помощью:

$ awk 'NR==1{print $3}' file2
-81.883,

Однако, это также включает запятую, которая, предположительно, вам не нужна. Чтобы избежать этого, можно указать awk использовать либо пробел либо запятую в качестве разделителей полей с помощью флага -F:

$ awk -F", " 'NR==1{print $3}' file2
-81.883

Awk позволяет задать переменную в командной строке с помощью опции -v:

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

Так, вы можете выполнить awk -vfoo="-81. 833" {...} и это сделает значение -81.33 доступным в качестве переменной foo в сценарии awk. Если объединить это с подстановкой команд, можно передать вывод первой команды awk (нужное вам значение) в качестве переменной (называемой, например, i) во второй сценарий, который заменит 11-е поле значением переменной i:

$ awk -vi="$(awk -F", " 'NR==1{print $3}' file2)" '{$11=i}1;' file1
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H

2
02.12.2017, 06:11
2 ответа

Попробуйте:

sed -E 's/.*(up.*), [[:digit:]]+ user.*/\1/'

Примеры

Это примеры из вопроса:

$ cat upfile
19:52  up 14 mins, 2 users, load averages: 2.95 4.19 4.31
8:03 up 52 days, 20:47, 3 users, load averages: 1.36 1.42 1.40
22:19 up 54 days, 1 min, 4 users, load averages: 2.08 2.06 2.27

Команда sed выдает:

$ sed -E 's/.*(up.*), [[:digit:]]+ user.*/\1/' <upfile
up 14 mins
up 52 days, 20:47
up 54 days, 1 min

Как это работает

Мы используем одну подстановочную команду:

s/.*(up.*), [[:digit:]]+ user.*/\1/
  • Первый .*совпадает с началом строки.

  • (up.*)сопоставляет слово up и следующий за ним текст и сохраняет его в группе 1.

  • , [[:digit:]]+ usersсоответствует запятой, за которой следует пробел, за которым следует одна или несколько цифр, за которым следует пробел, за которым следует строка users.

  • Второй .*соответствует всему после user.

Мы заменяем все это группой 1, обозначенной \1.

Совместимость

Это выше должно работать как на BSD/OSX, так и на современном Linux. В очень старых Linux может потребоваться заменить -Eна-r:

sed -r 's/.*(up.*), [[:digit:]]+ user.*/\1/'

Perl-версия

$ perl -pe 's/.*(up.*), [[:digit:]]+ user.*/$1/' <upfile
up 14 mins
up 52 days, 20:47
up 54 days, 1 min
1
27.01.2020, 22:03

Я использую эту (адаптацию для включения единиц, если это необходимо):

#!/usr/bin/awk -f

    BEGIN {
      while ("uptime" | getline)
        gsub(/,/,"")
        if (NF==10)
          print $3
        else if (NF==11)
          print $3,$4
        else if (NF==12)
          print $3,$4,$5
        else
          print $3,$4,$5,$6
      close("uptime")
    }
2
27.01.2020, 22:03

Теги

Похожие вопросы