AWK — вывести последний столбец вместе с пустым значением

AWK — вывести последний столбец вместе с пустым значением

Мы можем вывести последний столбец каждой строки в файле, используя функцию, $NFесли мы не знаем номер последнего столбца.

Но я столкнулся с трудностью: последний столбец имеет пустое значение.

Например,whoКоманда анализа

$ who
root     tty1         2018-01-25 09:36
root     pts/0        2018-05-30 07:39 (192.168.1.134)
root     pts/1        2018-05-28 23:12 (192.168.1.134)
root     pts/2        2018-06-01 10:01 (192.168.1.188)

Получение результата:

$ who | awk '{print $NF}'
09:36
(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

ожидаемый результат

(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

Расскажите мне о возможностях получения ожидаемого результата в одной строке.

ПРАВКА 1:Приведенный выше сценарий — всего лишь пример. Мне не нравится менять разделитель, чтобы добиться результата.

ПРАВКА 2:ничего (пустая строка вывода) из строк, которые имеют меньше полей, чем максимум

решение1

Чтобы вывести только последний столбец строк, имеющих максимальное количество столбцов, можно сделать что-то вроде:

who | awk '
  NF > max  {max = NF; output = ""}
  NF == max {output = output $NF ORS}
  END       {printf "%s", output}'

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

who | awk '
  NF > max {max = NF}
  {n[NR] = NF}
  NF == max {last[NR] = $NF}
  END {for (i = 1; i <= NR; i++) print n[i] == max ? last[i] : ""}'

решение2

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

С помощью awk(обратите внимание, что имя файла указано дважды):

awk -vfields=0 'FNR==NR {if (NF > fields) fields=NF; next} 
     NF >= fields { print $NF } NF < fields {print ""}' file file

Если fileсодержит

foo bar
one two three four
1 2 3
a b c d

это выводит четвертое поле или пустое для строк, в которых оно отсутствует:

четыре

г

Конечно, с каналом это не сработает, придется использовать временный файл.

Альтернативным решением может быть кэширование полей, которые должны быть напечатаны, до тех пор, пока не появится строка с большим количеством полей, как вОтвет Стефана.

решение3

Проверьте, совпадает ли 5-е поле \(.*\), и выведите его, если совпадает.

who | awk '$5 ~ /\(.*\)/{print $5}'

Если вас интересуют только ipадреса, то измените регулярное выражение:

who |  awk '$5 ~ /\((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\)/{print $5}'

решение4

Если вы хотите получить только последний столбец, если этот столбец доступен, используйте тот факт, что строки, которые вынехотим иметь только четыре столбца:

who | awk 'NF > 4 { print $NF }'

или, чтобы получить аналогичные данные,

w -hi | awk '{ print $3 }'

Связанный контент