Получите первое соответствие шаблону в строке, не использующей разрез

имея кучу текстов, подобных этому (с целью максимально упрощения теста и хранения данных):

first 1 is the real 2 time the word matched 3 appeared on the previous line but is 4 the fourth. Every line can have more numbers 5 because numbers 6 are everywhere I need to extract the number just after the word 7 that precedes 8 

Команда grep которую я тестирую, чтобы извлечь первое совпадение для числа сразу после слова:

 grep -Eoi ' [0-9]{1}' 

выход:

  1 2 3 4 5 6 7 8 

Желаемый результат:

  1 4 5 7 

Не разрешается использовать cut или awk .

5 Solutions collect form web for “Получите первое соответствие шаблону в строке, не использующей разрез”

Я подозреваю, что это своего рода упражнение, осваивающее только grep. Чистым решением grep является следующее:

В одной строке:

 echo "first 1 is the real 2 time the word matched 3 " |grep -Eo '[0-9]' |grep -m1 -E '[0-9]' 

К сожалению, использование grep -m1 в первом grep не дает требуемого результата.

В файле со многими строками вы должны использовать цикл:

 while read -r line; do grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]' done < file.txt 

Или в одной командной строке:

 while read -r line; do grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]';done < a.txt 

Выход по желанию.

Можно ли использовать sed ?

 $ sed 's/[^[[:digit:]]*\([[:digit:]]\).*/\1/' << EOF > first 1 is the real 2 time the word matched 3 > appeared on the previous line but is 4 the fourth. > Every line can have more numbers 5 because numbers 6 are everywhere > I need to extract the number just after the word 7 that precedes 8 > EOF 1 4 5 7 

Вы можете использовать две команды grep , сначала сопоставляя и возвращая все до первой последовательности десятичных цифр, затем сопоставляя и возвращая только цифры:

 grep -Eo '^[^0-9]*[0-9]{1,}' file | grep -Eo '[0-9]{1,}' 

[ПРИМЕЧАНИЕ. Я использую {1,} поскольку AFAIK {1} избыточен, и я предполагаю, что вы хотите сопоставить десятичные последовательности.]

Если вам разрешено использовать режим PCRE, и ваш grep поддерживает его, вы можете сделать то же самое в одном grep , используя утверждение переменной ширины переменной \K :

 grep -Po '^[^0-9]*\K[0-9]+' file 

или (чуть более компактно, используя perl-стиль \d для десятичной цифры):

 grep -Po '^[^\d]*\K\d+' file 

Или, поскольку вы не говорите, что вам не разрешено использовать perl , вы можете разделить поля, разделенные пробелами, а затем найти первое поле со всеми цифрами:

 perl -MList::Util=first -alne 'print first { /^\d+$/ } @F' 

как насчет этого sed и grep

 $ sed "s/\([0-9]\)/\n\1\n/" input.txt | grep "^.$" 1 4 5 7 

Вы можете попробовать следующее:

 grep -Eon ' [0-9]{1}' | sort -k1,1 -u 

Выход будет следующим: (не уверены, являются ли номера строк разблокировками):

 1: 1 2: 4 3: 5 4: 7 

В качестве альтернативы это выражение даст вам нужный результат:

 grep -Eon ' [0-9]{1}' | sort -k1,1 -u | grep -o ' .*' 

Выход (ваш выходной образец включает в себя ведущие пробелы):

  1 4 5 7 
  • Как получить код выхода grep, но распечатать все строки?
  • Как удалить первую точку перед первым номером?
  • grep -f patternfile не находит ничего или слишком сильно в зависимости от содержимого шаблона
  • Как удалить определенные ключи из списка слов?
  • Использование регулярных выражений для поиска списка слов. Поиск двух букв вместо 3. Почему?
  • Как найти текст, скопировать его и вставить в следующую строку в файле?
  • Как связывать линии между шаблоном начала и конца?
  • Почему не матч SHA?
  • Как анализировать файл данных для извлечения определенных данных и формата для другого использования?
  • Сортировка одного файла по строке на основе другого файла
  • чтение ввода в sed
  • Linux и Unix - лучшая ОС в мире.