1

Через скрипт я обрабатываю построчно некий текст для поиска совпадений по шаблону, столкнулся с такой проблемой...
после того как sed нашел совпадение в определнной строке, он ее должен вывести командой sed  -n '$ENUM  p' где $ENUM это каунтер с номером обрабатываемой строки, но так не получается вставить переменную - выпадает ошибка
sed: -e выражение #1, символ 3: лишние символы после команды

что за хреть...как мне вставить переменную в sed ...кто знает подскажите пожалуйста!?

P.S. Если вместо $ENUM написать допустим любую цифру, все работает - выводится соотв. строка.

2

Вопрос закрыт...сам дурак не попробовал вот так sed  -n ''$ENUM'  p'

3

создавайте подобные темы, пожалуйста, в более подходящих разделах

4

vadoz пишет:

sed  -n ''$ENUM'  p'

зачем тут вообще кавычки-то?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

5

vadoz пишет:

Через скрипт я обрабатываю построчно некий текст для поиска совпадений по шаблону, столкнулся с такой проблемой...
после того как sed нашел совпадение в определнной строке, он ее должен вывести командой sed

эх... А одной командой это сделать не судьба? Обязательно надо получать какой-то номер, потом ещё команду с номером запускать...
facepalm.jpg

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

6

Если не поставить кавычки не будет работать
Например:

[root@localhost scripts]# temp_var=4
[root@localhost scripts]# ls -l | sed -n '4 p'
-rwxr-xr-x 1 root root 1388 Мар 13 14:44 get_hw_info
[root@localhost scripts]# ls -l | sed -n '$temp_var p'
sed: невозможно найти метку для перехода к `emp_var'
[root@localhost scripts]# ls -l | sed -n ''$temp_var' p'
-rwxr-xr-x 1 root root 1388 Мар 13 14:44 get_hw_info
[root@localhost scripts]#

7

drBatty пишет:
vadoz пишет:

Через скрипт я обрабатываю построчно некий текст для поиска совпадений по шаблону, столкнулся с такой проблемой...
после того как sed нашел совпадение в определнной строке, он ее должен вывести командой sed

эх... А одной командой это сделать не судьба? Обязательно надо получать какой-то номер, потом ещё команду с номером запускать...
facepalm.jpg

А как получить номер считываемой строки из цикла for?

8 (14.03.2012 17:01:37 отредактировано NoXi0uZ)

В sed вроде = выводит номер, обрабатываемой строки.

Тогда

sed -n -e "/keyword/=" <inputfile> 

выведет номер строки со словом keyword.

github.com/cocaine

9

vadoz пишет:

А как получить номер считываемой строки из цикла for?

а разве вам этот номер нужен?

NoXi0uZ пишет:

В sed вроде = выводит номер, обрабатываемой строки.

да. выводит, только не туда эта команда выводит  ac

NoXi0uZ пишет:

выведет номер строки со словом keyword.

выведет. только это не нужно. Кстати, -e тоже не нужно. А что нужно, ТС тщательно скрывает...

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

10

DATA_FOR_CHECK=`cat /etc/syslog.conf | sed -n '/^#/ !p' | sed -n '/^$/ !p' | sed s/' \+'/' '/g`

for i in ${`${DATA_FOR_CHECK} | cut -f1`};
do
.
.
.

Почему подстановка команды не работает в цикле ? for i in ${`${DATA_FOR_CHECK} | cut -f1`};

11

vadoz, эх... Мне не верите? Ну здесь почитайте что умные дядьки из IBM советуют: http://www.ibm.com/developerworks/aix/l … abits.html

vadoz пишет:

Почему подстановка команды не работает в цикле ? for i in ${`${DATA_FOR_CHECK} | cut -f1`};

потому-что в вашем коде мне без стакана не разобраться. Как и вашему интерпретатору. Зачем такие сложности-то? У вас коммерческий проект, и вы боитесь, что ваш код будет украден конкурентами?  :o

vadoz пишет:

DATA_FOR_CHECK=`cat /etc/syslog.conf | sed -n '/^#/ !p' | sed -n '/^$/ !p' | sed s/' \+'/' '/g`

это четырёхэтажное матерное ругательство нужно сократить до одной команды sed. Причём ещё и проверить, что там оно вам возвращает. Вполне может быть, что совсем не то  ac

vadoz пишет:

Почему подстановка команды не работает в цикле ?

работает. только не так, как вы ожидаете.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

12

DATA_FOR_CHECK=`cat /etc/syslog.conf | sed -n '/^#/ !p' | sed -n '/^$/ !p' | sed s/' \+'/' '/g`

Я с sed еще толком не разобрался, а так ....разбил на небольшие блоки и мне понятней потом самому в этом разобраться smile

13

vadoz пишет:

Я с sed еще толком не разобрался, а так ....разбил на небольшие блоки и мне понятней потом самому в этом разобраться

вам это только так кажется. Начнём с того, что sed -n '/условие/!p' это масло масленное. Вам надо удалить строчку по условию? Ну так и пишите sed '/условие/d'
Далее, в одной команде можно сделать два действия. Например sed '/условие1/d; /условие2/d' (пробел после ; тут только для удобочитаемости)
Кроме того, простые условия можно группировать в одном регулярном выражении: sed -r '/условие1|условие2/d', но самое важное в том, что sed это УЖЕ цикл, который выполняется для всех строчек входного текста. ОЧЕНЬ плохая идея делать цикл с таким же циклом. Хотя-бы потому, что это непонятно и очень медленно.

vadoz пишет:

sed s/' \+'/' '/g

вот это я с трудом понял. Замените на sed -r 's/\s+/ /', ибо это лучше читается, и обычно именно это и требуется (вы потом строчку в bash суёте, а для него всё едино, что пробелы, что табуляции, но вот \r может привести к проблемам. Хотя это тоже пробельный символ, но рисуется он совсем не как пробел).

vadoz пишет:

| cut -f1

а вот этим вы чего хотели добиться? вывести всё до первого пробела? ну если уж вам не мила sed, которая это делает так sed 's/ .*//', дык дочитайте мануал cut до конца

man cut пишет:

     -d, --delimiter=DELIM
              use DELIM instead of TAB for field delimiter

что-то я сомневаюсь, что у вас в /etc/syslog.conf поля разделяются исключительно TAB'ом. (хотя от Red Hat можно ожидать и не такой гадости  wink )

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

14

drBatty пишет:

вывести всё до первого пробела? ну если уж вам не мила sed, которая это делает так sed 's/ .*//'

не понял это место...
. любой символ ,кроме \n.
Как

  sed 's/ .*//' 

выведет все до первого пробела? или я не так понял цель этой штуки ,она ж все стирает

ИМХО, что-то вроде

 sed 's/\s.*//'  

  должно быть.

github.com/cocaine

15

NoXi0uZ пишет:

    sed 's/ .*//'
не понял это место...

там не просто точка, а ПРОБЕЛ перед точкой. Потому удаляется не всё, а только первый пробел, и всё остальное. А вот s/.* // удаляет не всё до первого пробела, а всё до последнего.

NoXi0uZ пишет:

sed 's/\s.*//' 
  должно быть.

ну можно и так конечно. Так оно даже лучше. Пустые строчки тоже надо удалять так s/^\s*$/, потому-что в пустых строчках могут быть пробельные символы. И на хвостах тоже могут быть. Из MS-DOS подобных ос постоянно приходят файлы с \r на конце.

NoXi0uZ пишет:

. любой символ ,кроме \n.

неправильно. \n это тоже символ. И кстати тоже пробельный, и матчится и точкой и \s тоже. Другое дело, что sed обычно его хоть и читает, но в строчку для обработки не включает. Однако "обычно" не значит "всегда". Ну и ещё как всегда напомню, что точка матчит не всё. По стандарту с точкой совпадают любые символы, однако по другому стандарту, не все последовательности байтов в юникоде являются символами. Потому s/.*// ВНЕЗАПНО стала стирать не все строчки, и пришлось делать новую команду z для этого ac

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

16

Вообще цель скрипта - прочитать файл syslog.conf и проанализировать на наличие параметров отвечающих за регистрацию (допустим авторизации ) - параметр auth или authpriv.

Таким образом я командой DATA_FOR_CHECK=`cat /etc/syslog.conf | sed '/^#/d;/^$/d' | sed -r 's/\t+/ /;s/\s+/ /'` - записываю в переменную все параметры игнорируя закоменченные и пустые строки (sed '/^#/d;/^$/d'),
при этом между селекторами (auth или authpriv) и местом записи событий  должен остаться один пробел для того, чтобы получилось два столбика из селекторов и места записи логов - вот так:

*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.info /var/log/secure
auth.* /var/log/secure-auth
daemon.* /var/log/daemon
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg *
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
user.* /var/log/userlog

После чего выполняется вот эта CENSORED для сравления уровней важности сообщений....но оно еще не докончено....
#Уровень важности сообщений syslog
LEVEL[0]="emerg"
LEVEL[1]="alert"
LEVEL[2]="crit"
LEVEL[3]="err"
LEVEL[4]="warning"
LEVEL[5]="notice"
LEVEL[6]="info"
LEVEL[7]="debug"
LEVEL[8]="*"

#Построчное считывание параметров системы регистрации событий, записанных в переменную DATA_FOR_CHECK------------------------------------
for i in ${DATA_FOR_CHECK};
do

   #Поиск параметров auth, authpriv отвечающих за безопасность и авторизацию в системе
   if [[ ${i} == *"auth"* ]] || [[ ${i} == *"authpriv"* ]] || [[ ${i} == *"*."* ]]; then
     
      for index in 0 1 2 3 4 5 6 7 8
      do
          VAR_TEMP=`cat /etc/syslog.conf | sed '/^#/d;/^$/d'| sed -r 's/\t+/ /' | sed -r 's/\s+/ /' | sed -n ''$N' p' | cut -f2`

          if [[ ${i} == *"auth.""${LEVEL[index]}"* ]] || [[ ${i} == *"authpriv.""${LEVEL[index]}"* ]]; then
          echo 'Параметры отвечающие за регистрацию событий авторизации ==>' "${i}"'  ''записываются в файл ==>' "${VAR_TEMP}"

          elif [[ ${i} == *"*.""${LEVEL[index]}"* ]] && [[ ${i} != *"authpriv.none"* && ${i} != *"auth.none"* ]]; then
      echo 'Параметры отвечающие за регистрацию событий авторизации ==>' "${i}"'  ''записываются в файл ==>' "${VAR_TEMP}"
         
          break
          fi

      done

      EXISTANS_FLAG=true     
   
      #Поиск ключевого слова "none" для параметров auth и auhpri, отменяющего регистрацию данных событий----------------------------------
      if [[ ${i} == *auth.none* ]] || [[ ${i} == *authpriv.none* ]] || [[ ${i} == *"*.none"*  ]]; then
      FLAG=false

      else
      FLAG=true

      fi
   fi
N=$[ $N + 1 ]
done

А цель получить запись такого вида :

Параметры отвечающие за регистрацию событий авторизации ==> authpriv.info  записываются в файл ==> auth.* /var/log/secure-auth
Параметры отвечающие за регистрацию событий авторизации ==> auth.*  записываются в файл ==> mail.* -/var/log/maillog
Параметры отвечающие за регистрацию событий авторизации ==> *.emerg  записываются в файл ==>


Только вот не могу понять почему в последней строчке:
Параметры отвечающие за регистрацию событий авторизации ==> *.emerg  записываются в файл ==>
в конце не пишется * хотя она есть в конфиге???

17

drBatty пишет:

там не просто точка, а ПРОБЕЛ перед точкой

мой косяк, не заметил)

Про . и \n читал в книге  Девид Бизли Python: Полный справочник, стр 354. Дословно там написано:

. - любой символ, кроме символа перевода строки.

Наверняка это может быть отличием в трактовке питонячих регэкспов и регэкспов в sed (а вообще и перевода книги). Учту на будующее.

github.com/cocaine

18

vadoz пишет:

Вообще цель скрипта - прочитать файл syslog.conf и проанализировать на наличие параметров отвечающих за регистрацию (допустим авторизации ) - параметр auth или authpriv.

вроде вот эта утилита http://sourceforge.net/projects/watchlog/ делает тоже самое? Не?

vadoz пишет:

Уровень важности сообщений syslog

а где у вас syslog читается?

vadoz пишет:

echo 'Параметры отвечающие за регистрацию событий авторизации ==>' "${i}"'  ''записываются в файл ==>' "${VAR_TEMP}"

почему нельзя написать так?

echo "Параметры отвечающие за регистрацию событий авторизации ==> ${i}  записываются в файл ==>${VAR_TEMP}"

зачем эта куча кавычек?

vadoz пишет:

в конце не пишется * хотя она есть в конфиге???

я тоже с вашими кавычками запутался. Наверное bash эти звёздочки раскрыл. Он ведь все звёздочки раскрывает, что может. Просто * всегда раскрывается в список не скрытых файлов в текущем каталоге. Он у вас очевидно пуст.

vadoz пишет:

if [[ ${i} == *"auth.""${LEVEL[index]}"* ]] || [[ ${i} == *"authpriv.""${LEVEL[index]}"* ]]; then

такой код называется write only. Написал, и больше НИКОГДА не трогай.  ac
сотрите, и напишите нормально. Я ничего не понял.

NoXi0uZ пишет:

Про . и \n читал в книге  Девид Бизли Python

ну что касается юникода, то американцев этот вопрос слабо волнует, всякие перлы до сих пор считают Ф за два символа. Думаю пайтон не исключение, и тупо не умеет юникод(по умолчанию). Печально конечно, но что делать... А что касается \n, то тут вопрос намного более интересный, и дело тут в том, включен/выключен в ваших регулярках мультистрочный режим.
Не помню как в пайтоне, но в sed (а так же в перле, и в Over9000 других ЯП) мультистрочный режим таки ВЫКЛЮЧЕН.

 Консоль:
$ echo -e "a\nx" | sed 'N' # эта команда объединяет две строки в одну строчку с \n посередине.
a
x
# Ну всё равно это выглядит как 2 строки
$ echo -e "a\nx" | sed 'N;s/.*/+++/'
+++
# но вот меняется таки обе этих строчки, вместе с \n
$ echo -e "a\nx" | sed 'N;s/.*/+++/m' # в мультистрочном режиме sed учитывает, что строчек на самом деле две, и меняет не всё, а только первую строчку
+++
x
# первое совпадение...
$ echo -e "a\nx" | sed 'N;s/.*/+++/gm'
+++
+++
# или все совпадения но отдельно по строчкам

и да, читать надо info sed или  мой перевод

«.» (точка)
    Совпадает с любым одиночным символом, включая символ перевода строки.

лучше таки оригинал, ибо в этой вашей CentOS как всегда какая-нить древность ac
А ну, да:

 Консоль:
-bash-3.2# sed 'z'
sed: -e expression #1, char 1: unknown command: `z'
-bash-3.2# sed --version
GNU sed version 4.1.5
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,
to the extent permitted by law.

не система, а полная задница  ah

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

19

А как вывести элементы массива диапазоном ....ничего по этому поводу не нашел..либо все либо выборочно по инжексу элемента массива??

Вот массив как вывести допустим элементы со 2 по 8 не перечесляя их?
LEVEL[0]="*"
LEVEL[1]="emerg"
LEVEL[2]="alert"
LEVEL[3]="crit"
LEVEL[4]="err"
LEVEL[5]="warning"
LEVEL[6]="notice"
LEVEL[7]="info"
LEVEL[8]="debug"

20

vadoz пишет:

А как вывести элементы массива диапазоном

только ручками, баш не питон...

ЗЫ: пользуйтесь тегами code/console для оформления....

95% процентов проблем находятся между клавиатурой и стулом.

21 (16.03.2012 10:34:49 отредактировано drBatty)

vadoz пишет:

Вот массив как вывести допустим элементы со 2 по 8 не перечесляя их?

for x in {2..8}
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

22

Fat-Zer, эх... не стыдно? "питон" во первых не "питон", а пайтон, а во вторых, умеет он ровно столько же, сколько и баш. man тьюринг полнота.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

23

drBatty пишет:

"питон" во первых не "питон", а пайтон

во-первых, не придирайтесь к словам.

drBatty пишет:

умеет он ровно столько же, сколько и баш.

во-вторых, столько же, но man ручками.

95% процентов проблем находятся между клавиатурой и стулом.

24

Fat-Zer пишет:

во-первых, не придирайтесь к словам.

а не надо их коверкать.

Fat-Zer пишет:

во-вторых, столько же, но man ручками.

а выше показано, что без всяких ручек {x..y..z} всё отлично работает. Если вы этого не знали - ваши проблемы.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

25

drBatty, это и есть ручками. ИМХО ТС хотел видеть что-то вроде echo array[2:8]. а такого в баше нет...
ладно... спорить бесполезно, ибо, судя по соседним веткам, вы сегодня снова не с той ноги встали...

95% процентов проблем находятся между клавиатурой и стулом.

26

Fat-Zer пишет:

это и есть ручками. ИМХО ТС хотел видеть что-то вроде echo array[2:8]. а такого в баше нет

а надо? смысл-то какой?

Fat-Zer пишет:

ладно... спорить бесполезно, ибо, судя по соседним веткам, вы сегодня снова не с той ноги встали...

на такой вброс г-на вентилятор я могу ответить только сцылкой: http://lurkmore.to/42

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)