Поиск текста между двумя конкретными символами или строками

Скажем, у меня есть строки вроде этого:

*[234]* *[23]* *[1453]* 

где * представляет любую строку (кроме строки формы [number] ). Как я могу разобрать эти строки с помощью утилиты командной строки и извлечь число между скобками?

В более общем плане, какой из этих инструментов cut , sed , grep или awk подходит для такой задачи?

  • захватить текст по шаблону с началом и конечным тегом в нескольких строках
  • Изменение существующего файла непосредственно для замены «foo» на «bar» ТОЛЬКО для строк, содержащих «baz»,
  • Помогите с пониманием регулярного выражения
  • Замена шаблона в строке, предшествующей другому интересующему образцу
  • исключить строки из файла на основе определенных значений в определенных столбцах
  • Текст цензора с регулярным выражением
  • Команда командной строки для добавления пробела к регулярному выражению
  • Regex, который будет grep-номера после определенной строки
  • 4 Solutions collect form web for “Поиск текста между двумя конкретными символами или строками”

    Если у вас есть GNU grep, вы можете использовать опцию -o для поиска регулярного выражения и вывода только соответствующей части. (Другие реализации grep могут отображать только целую строку.) Если в одной строке есть несколько совпадений, они печатаются на отдельных строках.

     grep -o '\[[0-9]*\]' 

    Если вам нужны только цифры, а не скобки, это немного сложнее; вам нужно использовать утверждение с нулевой шириной: регулярное выражение, которое соответствует пустой строке, но только в том случае, если ему предшествуют или следует в зависимости от случая, с помощью скобки. Утверждения о нулевой ширине доступны только в синтаксисе Perl.

     grep -P -o '(?<=\[)[0-9]*(?=\])' 

    С sed вам нужно отключить печать с помощью -n и сопоставить всю строку и сохранить только соответствующую часть. Если в одной строке есть несколько возможных совпадений, выводится только последнее совпадение. См. « Извлечение регулярного выражения, совпадающего с« sed », без печати окружающих символов для получения дополнительной информации об использовании sed здесь.

     sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p' 

    или если вам нужны только цифры, а не скобки:

     sed -n 's/^.*\[\([0-9]*\)\].*/\1/p' 

    Без grep -o , Perl является инструментом выбора здесь, если вы хотите что-то, что является простым и понятным. В каждой строке ( -n ), если строка содержит совпадение для \[[0-9]*\] , напечатайте это соответствие ( $& ) и новую строку ( -l ).

     perl -l -ne '/\[[0-9]*\]/ and print $&' 

    Если вам нужны только цифры, поместите круглые скобки в регулярное выражение, чтобы разграничить группу, и напечатайте только эту группу.

     perl -l -ne '/\[([0-9]*)\]/ and print $1' 

    PS Если требуется только одна или несколько цифр между скобками, измените [0-9]* на [0-9][0-9]* или на [0-9]+ в Perl.

    Вы не можете сделать это с помощью cut .

    1. tr -c -d '0123456789\012'
    2. sed 's/[^0-9]*//g'
    3. awk -F'[^0-9]+' '{ print $1$2$3 }'
    4. grep -o -E '[0-9]+'

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

    Если вы имеете в виду извлечение набора последовательных цифр между несимметричными символами, я думаю, что sed и awk являются лучшими (хотя grep также может дать вам совпадающие символы):

    sed : вы можете, конечно, сопоставить цифры, но, возможно, интересно сделать обратное, удалить нецифровые числа (работает, пока есть только одно число в строке):

     $ echo nn3334nn | sed -e 's/[^[[:digit:]]]*//g' 3344 

    grep : вы можете сопоставлять последовательные цифры

     $ echo nn3334nn | grep -o '[[:digit:]]*' 3344 

    Я не показываю пример awk потому что у меня есть нулевой опыт; Интересно отметить, что хотя sed – швейцарский нож, grep дает вам более простой и понятный способ сделать это, что также работает для более чем одного номера на каждой строке ввода ( -o только печатает соответствующие части вход, каждый в отдельной строке):

     $ echo dna42dna54dna | grep -o '[[:digit:]]*' 42 54 

    Поскольку было сказано, что это невозможно сделать с помощью cut , я покажу, что легко получить решение, которое по крайней мере не хуже, чем некоторые другие, хотя я не одобряю использование cut как " лучшее (или даже очень хорошее) решение. Следует сказать, что любое решение, не предназначенное специально для *[ и ]* вокруг цифр, делает упрощающие предположения и поэтому подвержено ошибкам на примерах, более сложных, чем тот, который задает ассер (например, цифры вне *[ и ]* , которые не должны отображаться). Это решение проверяет, по крайней мере, для скобок, и оно может быть расширено, чтобы проверить звездочки (слева как упражнение для читателя):

     cut -f 2 -d '[' myfile.txt | cut -f 1 -d ']' 

    Это использует параметр -d , который определяет разделитель. Очевидно, вы могли бы также транслировать в выражение cut вместо чтения из файла. Хотя cut , вероятно, довольно быстро, так как это просто (без механизма регулярных выражений), вы должны вызывать его по крайней мере дважды (или несколько раз для проверки на * ), что создает некоторые издержки процесса. Единственное реальное преимущество этого решения состоит в том, что оно довольно читаемо, особенно для случайных пользователей, не очень разбирающихся в конструкциях регулярных выражений.

    Linux и Unix - лучшая ОС в мире.