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

Я ищу строку ::=BEGIN и хочу применить условие, чтобы проверить, было ли слово найдено.

Итак, я имею в виду что-то вроде этого:

if (sed command does find a match for "::=BEGIN")
then i=1 
else i=0

Кроме того, я хочу, чтобы 1 (если да найдено) и 0 (не найдено) были помещены в переменную «i».

Пожалуйста, помогите мне. Также предоставьте объяснение решения! Спасибо!

7
задан 11 June 2015 в 17:27

5 ответов

grep делает то задание достаточно хорошо.

$ echo "::=BEGIN" > testfile1.txt

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND

$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND

То, что делает код, просто запускает тихий поиск в подоболочке. && , или логичный И операнд, проверки, если первая команда успешно выполнилась, и если это сделало, затем это работает echo "FOUND" . || проверки, если то эхо было выполнено, т.е. если мы нашли что-нибудь. Второе эхо работает, только если первая команда перестала работать.

Вот awk версия:

$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT

$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND

Основная идея здесь состоит в том, чтобы установить i кому: NOTFOUND, и если мы находим, что строка - изменяет его на FOUNDIT . В конце после того, как первый набор закончил обрабатывать файл, мы распечатаем i, и это скажет нам, если мы нашли что-то или нет.

Править: В комментарии Вы упомянули, что хотите поместить результат в переменную. Shell уже обеспечивает переменную, которая сообщает о статусе выхода предыдущей команды, $0. Статус выхода 0 успехов средств, все остальное - сбой. Например,

$ grep "::=BEGIN" -q testfile1.txt  
$ echo $?
0

Если Вы хотите использовать статус выхода в переменной, можно сделать это как так: MYVAR=$(echo $?). Помните, $? статус выхода отчета предыдущей команды. Таким образом, необходимо использовать это право после команды grep.

Если Вы хотите все еще использовать мой ранее awk и grep остроты, можно использовать тот же прием MYVAR=$() и поместите любую команду, которую Вы хотите между фигурными скобками. Вывод будет присвоен переменной MYVAR.

6
ответ дан 11 June 2015 в 17:27

С GNU sed (как установлен по умолчанию в любой системе Ubuntu):

{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile

Некоторые факты об этом ответе:

  1. sed Qвход uits сразу же, как только самое первое соответствие найдено где угодно в файле - что означает это, больше не тратит впустую время, продолжающее считать infile.

  2. sed возвраты в его коде выхода числовое значение 0 или 1 в зависимости от того, не могло ли это найти обращенный regexp.

  3. $i установлен на sedвозвратитесь на выход.

  4. { группировка ; } используется для устойчивой обработки любой возможной ошибки перенаправления - $i не установлен в случае, оболочка не может открыть файл вообще, таким образом избежав ложных положительных сторон.

Это, вероятно, не должно быть предпочтено grep -q, Тем не менее, который может в основном также сделать все вышеупомянутое (если наоборот), сделайте это POSIXly, и обычно быстрее.

Уже данный grep -q ответ является очень хорошим, но, немного более кратким:

grep -q pattern ./infile; i=$((!$?))
5
ответ дан 11 June 2015 в 17:27

Можно использовать это:

#!/bin/bash
while IFS= read -r line; do
    case "$line" in *::=BEGIN*) i=1 && break;;         
                               *) i=0
    esac
done <file.txt

Это будет искать файл file.txt линию за линией и если соответствие ::=BEGIN нашло, что установит переменную i=1 и выход. Если никакое соответствие не будет найдено, переменная будет установлена как i=0.

0
ответ дан 11 June 2015 в 17:27

Мой sed версия

sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'

для хранения в переменной i:

i=$(sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}')
<час>

Пример:

$ echo "::=BEGIN" > foo
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1
$ echo "::=NOT_BEGIN" > foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
0
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1
<час>

Объяснение:

  • , Если ::=BEGIN найден, распечатайте 1 и переход к next
  • , Если ::=BEGIN не найден, распечатайте 0
0
ответ дан 11 June 2015 в 17:27

sed (Потоковый Редактор), не правильный инструмент для такого рода вещей: можно просто использовать a bash if оператор для соответствия входу против regex:

#!/bin/bash

#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
  • input="$(< inputfile)": присваивает содержание inputfile к переменной $input
  • [[ "$input" =~ ::=BEGIN ]] && i=1 || i=0: соответствует regex ::=BEGIN против содержания переменной $input; если существует соответствие, оно присваивается 1 кому: $i, иначе это присваивается 0 кому: $i
2
ответ дан 11 June 2015 в 17:27

Другие вопросы по тегам:

Похожие вопросы: