LINUX.ORG.RU

Grep и регулярное выражение

 , ,


1

3

Добрый день!

Нарвался на статьи на Хабре, по Башу(по местным комментам я понял уже, что материал не ахти, но всё же). Есть там вот такой пример, «как вытащить первого пользователя из выдачи команды who» и записать в переменную:

logged_on=$(who | grep -i -m 1 $1 | awk ‘{print $1}’)

Как я не пытался выполнить этот код, всё тщетно. Во время выполнения ругается Grep:

Usage: grep [OPTION]… PATTERN [FILE]…

Понимаю, что проблема в том, что Grep’ом хотят вытащить первый элемент в первой строке, но Grep не умеет в ‘$0/$1/$2’ и т.д.

Статья на Хабре - есть перевод другой статьи, оригинала. Там эту задачу решают по-другому:

logged=$(who | awk -v IGNORECASE=1 -v usr=$1 ‘{ if ($1==usr) { print $1 }exit }’)

но в моём случае всё тоже тщетно, в переменную ничего не записывается. Почему? Определить не смог. Пробовал немного изменить код:

logged=$(who | awk ‘{BEGIN IGNORECASE=1; usr=$1} { if ($1==usr) { print $1 }exit }’)

но результат по прежнему нулевой.

Саму задачу я уже решил, совсем по другому, через костыль, но всё же хочу правильно всё понять и разобраться. Как решать задачу верно? Может у меня какой-то не сильно умный GREP, который не умеет в регулярные выражения, если я не спутал понятия конечно?

Update:

Прошу меня простить, на абзац ниже, написано, что скрипт будет вызываться с параметром(например, интересующий нас пользователь), который попадает в $1 и всё сразу работает. Не доглядел. Извините!

«как вытащить первого пользователя (ПОПАДАЮЩЕГО ПОД ШАБЛОН, ПЕРЕДАННЫЙ КАК ПЕРВЫЙ АРГУМЕНТ СКРИПТА) из выдачи команды who» и записать в переменную:

logged_on=$(who | grep -i -m 1 $1 | awk ‘{print $1}’)

Для проверки в терминале

set $USER
logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}')
echo $logged_on
futurama ★★★★ ()

grep -i -m 1 $1

в данном случае $1 это не аргумент для команды grep, а параметр командной строки, которым что-то передают в скрипт или в функцию и потом проверяют на соответствие выхлопа who.

logged_on=$(who | grep -i -m 1 $1 | awk ‘{print $1}’)

то есть всю команду следует читать так: грепом проверить выхлоп who на соответствие содержимому в $1, игнорировать строчные/прописные, остановиться на первой подходящей строке и с помощью awk вывести первое слово (юзернэйм) и занести его в значение переменной.

nerve ★★ ()
Последнее исправление: nerve (всего исправлений: 2)
Ответ на: комментарий от nerve

и с помощью awk вывести первое слово (юзернэйм)

Ну надо всё-таки либо упростить:

logged_on=$(who | grep -i -m 1 -o $1)

, либо sed, tr, cut, paste, fmt,… сюда понапихать.

anonymous ()
Ответ на: комментарий от vladstv

Если Вам не принципиально нужен awk - я бы советовал пример от anonymous.

#!/usr/bin/env bash

logged=$(grep -i -m 1 -o "$1" <(who))

echo "==== $logged"

Предполагаю, что по скорости отработки - данная версия будет быстрее.

i3wm ()

Так первого пользователя или того, имя которого передаешь в виде аргумента?

Если первого, то вариант с авком самый простой. А если того, который в виде аргумента, то проще сделать

if grep $1 <(who) ...
Yorween ()
Ответ на: комментарий от Yorween

Нет, все правильно

Правильно то, правильно. Но помечать как-нибудь, что это bash стоило бы. Кстати, никто не пробовал достучаться до ЛОР-воятелей, чтобы как-то различались блоки кода, в зависимости от того, что укажешь (sh, bash, python, c, c++,…)? Не?

anonymous ()