как использовать sed, awk, или простофилю для печати только, что подобрано?

Я вижу много примеров и страниц справочника о том, как сделать вещи как поиск-и-замена с помощью sed, awk, или простофиля.

Но в моем случае, у меня есть регулярное выражение, которое я хочу выполнить против текстового файла для извлечения определенного значения. Я не хочу делать поиск-и-замену. Это называют от удара. Давайте использовать пример:

Регулярное выражение в качестве примера:

.*abc([0-9]+)xyz.*

Пример ввел файл:

a
b
c
abc12345xyz
a
b
c

Столь же простой, как это звучит, я не могу выяснить, как назвать sed/awk/gawk правильно. То, что я надеялся сделать, из моего сценария удара, имейте:

myvalue=$( sed <...something...> input.txt )

Вещи, которые я попробовал, включают:

sed -e 's/.*([0-9]).*/\\1/g' example.txt # extracts the entire input file
sed -n 's/.*([0-9]).*/\\1/g' example.txt # extracts nothing
97
задан Stéphane 14 November 2009 в 08:34
поделиться

7 ответов

My sed (Mac OS X) didn Не работает с + . Вместо этого я попробовал * и добавил тег p для вывода совпадений:

sed -n 's/^.*abc\([0-9]*\)xyz.*$/\1/p' example.txt

Для сопоставления хотя бы одного числового символа без + я бы использовал:

sed -n 's/^.*abc\([0-9][0-9]*\)xyz.*$/\1/p' example.txt
42
ответ дан 24 November 2019 в 05:30
поделиться

Я использую perl , чтобы облегчить себе задачу. например,

perl -ne 'print $1 if /.*abc([0-9]+)xyz.*/'

Это запускает Perl, опция -n инструктирует Perl читать по одной строке из STDIN и выполнять код. Параметр -e определяет инструкцию для выполнения.

Инструкция запускает регулярное выражение в прочитанной строке, и, если оно совпадает, выводит содержимое первого набора скобок ( $ 1 ]).

Вы также можете сделать это с несколькими именами файлов в конце. например,

perl -ne 'print $ 1 if /.*abc([0-9 provided+)xyz.*/' example1.txt example2.txt

17
ответ дан 24 November 2019 в 05:30
поделиться

Если ваша версия grep поддерживает его, вы можете использовать параметр -o , чтобы вывести только часть любой строки, которая соответствует вашему регулярному выражению.

Если нет, то вот лучший sed , который я мог придумать:

sed -e '/[0-9]/!d' -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'

... который удаляет / пропускает без цифр, а для оставшихся строк удаляет все начальные и конечные нецифровые символы. (Я только предполагаю, что вы собираетесь извлечь число из каждой строки, содержащей его.)

Проблема с чем-то вроде:

sed -e 's/.*\([0-9]*\).*/&/' 

.... или

sed -e 's/.*\([0-9]*\).*/\1/'

... в том, что sed поддерживает только «жадное» совпадение ... поэтому первый. * будет соответствовать остальной части строки. Если мы не сможем использовать инвертированный символьный класс для достижения нежадного соответствия ... или версию sed с Perl-совместимыми или другими расширениями его регулярных выражений, мы не сможем извлечь точное совпадение с образцом из с пространством образца (линия).

я только догадываюсь, что вы хотите извлечь число из каждой строки, содержащей единицу).

Проблема с чем-то вроде:

sed -e 's/.*\([0-9]*\).*/&/' 

.... или

sed -e 's/.*\([0-9]*\).*/\1/'

... в том, что sed ] поддерживает только «жадное» совпадение ... поэтому первый. * будет соответствовать остальной части строки. Если мы не сможем использовать инвертированный символьный класс для достижения нежадного соответствия ... или версию sed с Perl-совместимыми или другими расширениями его регулярных выражений, мы не сможем извлечь точное совпадение с образцом из с пространством образца (линия).

я только догадываюсь, что вы хотите извлечь число из каждой строки, содержащей единицу).

Проблема с чем-то вроде:

sed -e 's/.*\([0-9]*\).*/&/' 

.... или

sed -e 's/.*\([0-9]*\).*/\1/'

... в том, что sed ] поддерживает только «жадное» совпадение ... поэтому первый. * будет соответствовать остальной части строки. Если мы не сможем использовать инвертированный символьный класс для достижения нежадного соответствия ... или версию sed с Perl-совместимыми или другими расширениями его регулярных выражений, мы не сможем извлечь точное совпадение с образцом из с пространством образца (линия).

5
ответ дан 24 November 2019 в 05:30
поделиться

Если вы хотите выбрать строки, удалите те биты, которые вам не нужны:

egrep 'abc[0-9]+xyz' inputFile | sed -e 's/^.*abc//' -e 's/xyz.*$//'

Он в основном выбирает нужные строки с помощью egrep , а затем использует ] sed , чтобы удалить биты до и после числа.

Вы можете увидеть это в действии здесь:

pax> echo 'a
b
c
abc12345xyz
a
b
c' | egrep 'abc[0-9]+xyz' | sed -e 's/^.*abc//' -e 's/xyz.*$//'
12345
pax> 

Обновление: очевидно, если ваша реальная ситуация более сложна, мне понадобятся RE изменен. Например, если у вас всегда было одно число, заключенное в ноль или более нечисловых чисел в начале и в конце:

egrep '[^0-9]*[0-9]+[^0-9]*$' inputFile | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'
1
ответ дан 24 November 2019 в 05:30
поделиться
gawk '/.*abc([0-9]+)xyz.*/' file
-3
ответ дан 24 November 2019 в 05:30
поделиться

Для awk. Я бы использовал следующий сценарий:

/.*abc([0-9]+)xyz.*/ {
            print $0;
            next;
            }
            {
            /* default, do nothing */
            }
-3
ответ дан 24 November 2019 в 05:30
поделиться

вы можете сделать это с помощью оболочки

while read -r line
do
    case "$line" in
        *abc*[0-9]*xyz* ) 
            t="${line##abc}"
            echo "num is ${t%%xyz}";;
    esac
done <"file"
-1
ответ дан 24 November 2019 в 05:30
поделиться
Другие вопросы по тегам:

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