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 и всё сразу работает. Не доглядел. Извините!



Последнее исправление: vladstv (всего исправлений: 2)

«как вытащить первого пользователя (ПОПАДАЮЩЕГО ПОД ШАБЛОН, ПЕРЕДАННЫЙ КАК ПЕРВЫЙ АРГУМЕНТ СКРИПТА) из выдачи команды 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 ★★★★★
()

Негде проверить на нескольких строках в who, но должно быть проще

who | awk 'NR=1 {print $1}'
anonymous
()

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)

Возвращает первую запись из найденных + первое слово.
Если нужна запись целиком - нужно убрать \$1 после print

#!/usr/bin/env bash
  
  awk "/$1/{print \$1; exit}" < <(who)

:wq

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

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

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

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

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

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

Точнее не куда! Просто надо было запускать скрипт с параметром. Спасибо вам!

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

Работает, но это немного не то. Этот скрипт будет вываливать имя пользователя из под которого его(скрипт) запускаешь. Спасибо вам!

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

set $USER

Это просто пример установки $1 в значение текущего пользователя

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

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

#!/usr/bin/env bash

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

echo "==== $logged"

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

i3wm
()

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

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

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

Вывести пустоту, конечно, проще, но задачу это не решает.

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

Нет, все правильно у @vodz. Перечитал пост ТСа и только заметил «записать в переменную». Первый раз взгляд зацепился за многократное «вытащить».

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

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

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

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

Правильно то, правильно. Но помечать как-нибудь, что это bash стоило бы.

В тегах стоит bash. Переписать на ash - не сложно:

read user other << EOF
`who`
EOF

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.