
Мы можем вывести последний столбец каждой строки в файле, используя функцию, $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 }'