5

Как я могу найти текстовый файл для этого шаблона в терминале Ubuntu и сохранить вывод в виде текстового файла?

Я ищу все между строкой "abc" и строкой "cde" в длинном списке данных.

Например:

blah blah abc fkdljgn cde blah
blah blah blah blah blah abc skdjfn cde blah

В приведенном выше примере я бы искал такой вывод:

fkdljgn
skdjfn

Важно, что я также могу сохранить вывод данных в виде текстового файла.

Могу ли я использовать grep или agrep, и если да, то какой формат?

2 ответа2

11

Чтобы получить вывод, который вы показываете, вы можете запустить

grep -Po 'abc \K.*(?= cde)'  file.txt > outfile.txt

P активирует Perl-совместимые регулярные выражения, которые поддерживают обходные пути, и \K что означает «отбросить все, что соответствовало этой точке». -o заставляет grep печатать только совпадающую часть строки, поэтому в сочетании с положительным прогнозом (?=cde) и \K , он будет печатать только символы между abc и cde . > outfile.txt сохранит результат в файле outfile.txt .

Некоторые другие подходы:

  • sed

    sed -r 's/.*abc (.+) cde.*/\1/' file.txt > outfile.txt
    

    Здесь круглые скобки фиксируют шаблон, и вы можете ссылаться на него как \1 . 's/source/replacement/' является оператором замещения и заменяет source replacement . В этом случае он просто удалит все, кроме того, что находится между abc и cde .

  • perl

    perl -pe 's/.*abc (.+) cde.*/$1/' file.txt > outfile.txt
    

    То же, что и выше, на самом деле -p означает «читать входной файл построчно, применять скрипт, заданный как -e и печатать.

  • awk

     awk -F'abc|cde' '{print $2}' file.txt > outfile.txt
    

    Идея здесь состоит в том, чтобы установить разделители полей на abc или cde . Предполагая, что эти строки уникальны в каждой строке, второе поле будет тем, которое находится между ними. Это, однако, включает в себя начальные и конечные пробелы, чтобы удалить их через другой awk:

    awk -F'abc|cde' '{print $2}' file | awk '{print $1}'
    
  • GNU awk (gawk). Вышеописанное прекрасно работает и в gawk , я включаю это в том случае, если вы хотите сделать что-то более сложное и хотите иметь возможность захватывать шаблоны.

    gawk '{print gensub(/.*abc (.*) cde.*/,"\\1", "g",$0);}' file.txt > outfile.txt
    

    Это та же основная идея, что и в perl и sed , но с использованием функции gensub () gawk.

3

Вы хотите использовать регулярное выражение для этого. Я не настолько опытен с регулярным выражением UNIX, но что-то вроде этого должно работать

grep -Po '(?<=abc ).*(?= cde)' test.txt > output.txt

Изменить: Синтаксическая ошибка произошла из-за пропущенных кавычек, хотя старое предложение не сработало, вы хотите использовать (?<=xxx) это называется проверочным утверждением нулевой ширины, и без < вы заглядываете в будущее. -P для активации регулярных выражений в стиле Perl и -o для печати только совпадений.

Пробовал это и работает нормально с текстовым файлом, содержащим abc mymatch cde .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .