Как распечатать все строки после соответствия в конец файла?

whereis git и Вы получаете путь к команде.

это просто, если мерзавец находится в Вас, СОЕДИНЯЮТ переменную каналом, в случае, если Вы установили ее не через Вас диспетчер пакетов, это более сложно, и необходимо использовать find или locate команды.

51
24.11.2012, 01:29
12 ответов

Принятие Вас хочет соответствовать целой строке Вашему шаблону GNU sed, это работает:

sed -n '/^dog 123 4335$/ { :a; n; p; ba; }' infile

Стандартный эквивалент:

sed -ne '/^dog 123 4335$/{:a' -e 'n;p;ba' -e '}' infile

Со следующим входом (infile):

cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

Вывод:

cat 13123 23424 
deer 2131 213132
bear 2313 21313

Объяснение:

  • /^dog 123 4335$/ поиски желаемого шаблона.
  • :a; n; p; ba; цикл, который выбирает новую строку от входа (n), печатает его (p), и ответвления назад к маркировке a :a; ...; ba;.

Обновление

Вот ответ, который прибывает ближе в Ваши потребности, т.е. шаблон в file2, держа от file1:

tail -n +$(( 1 + $(grep -m1 -n -f file2 file1 | cut -d: -f1) )) file1

Встроенный grep и сокращение находят первую строку, содержащую шаблон от file2, этого номера строки плюс, каждый передается хвосту, плюс каждый там для пропуска строки с шаблоном.

Если бы Вы хотите начать с последнего соответствия вместо первого соответствия, это было бы:

tail -n +$(( 1 + $(grep -n -f file2 file1 | tail -n1 | cut -d: -f1) )) file1

Обратите внимание, что не все версии хвоста поддерживают плюс нотация.

28
27.01.2020, 19:33
sed -e '1,/dog 123 4335/d' file1

Если необходимо считать шаблон из файла, заменить им в команду sed. Если файл содержит sed шаблон:

sed -e "1,/$(cat file2)/d" file1

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

sed -e "1,/$(sed 's/[][\\\/^$.*]/\\&/g' file2)/d" file1

Если Вы хотите, чтобы соответствие было целой строкой, не только подстрокой, перенести шаблон в ^…$.

sed -e "1,/^$(sed 's/[][\\\/^$.*]/\\&/g' file2)\$/d" file1
15
27.01.2020, 19:33
  • 1
    Это не будет работать, если шаблон будет на первой строке. GNU sed имеет 0,/dog.../d для этого. –  Stéphane Chazelas 10.06.2015, 12:48

Один способ использовать awk:

awk 'NR==FNR{a[$0];next}f;($0 in a){f=1}'  file2 file1

где file2 содержит Ваши шаблоны поиска. Во-первых, все содержание file2 хранится в массиве "a". Когда file1 обрабатывается, каждая строка проверяется по массиву и печатается, только если не присутствует.

5
27.01.2020, 19:33
  • 1
    я думаю OP, хочет произвести каждую строку после шаблона. –  Thor 23.11.2012, 13:41
  • 2
    @Thor: благодарит указать на это, обновил его теперь... –  Guru 23.11.2012, 13:57
  • 3
    Хорошо сделанный :). –  Thor 23.11.2012, 15:04

Так как awk явно не запрещен, вот мое предлагающее предположение, что 'кошка' является соответствием.

awk '$0 ~ /cat/ { vart = NR }{ arr[NR]=$0 } END { for (i = vart; i<=NR ; i++) print arr[i]  }' animals.txt
0
27.01.2020, 19:33

$ more +/"dog 123 4335" file1

14
27.01.2020, 19:33
  • 1
    Это также работает с less. –  brandizzi 26.05.2015, 16:40
  • 2
    , умный на терминале, но это на самом деле не работает при передаче по каналу его во что-то еще как tac. –  jcomeau_ictx 02.07.2015, 09:25
  • 3
    я использую его как это, $ больше + / "распознает мои слова" file1>>, file2 –  AMB 07.07.2015, 20:38
  • 4
    , Возможно, + был заменен -p в POSIX 7: pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html, но еще реализованный в util-linux 2.20.1. И это также печатает skipping.. и некоторые дополнительные новые строки (к stderr, который я ожидаю, так мог бы быть прекрасным). –  Ciro Santilli 新疆改造中心法轮功六四事件 14.09.2016, 15:41
  • 5
    , возможно, вещи изменился с тех пор? мой комментарий получил 3 upvotes, таким образом, это, возможно, было релевантно в то время... –  jcomeau_ictx 04.11.2017, 18:42

Если у вас достаточно короткий файл grep, может сработать:

grep -A5000 -m1 -e 'dog 123 4335' animals.txt

5000 - это просто моя догадка на "достаточно короткий", так как grep находит первое совпадение и выводит его вместе со следующими 5000 строками (файл не должен иметь столько строк). Если вы не хотите, чтобы это совпадение совпадало само по себе, то вам придется его отсечь, например,

grep -A5000 -m1 -e 'dog 123 4335' animals.txt | tail -n+2


Если вы не хотите, чтобы первое, но последнее совпадение было в качестве разделителя, то вы можете использовать это:
tac animals.txt | sed -e '/dog 123 4335/q' | tac

Эта строка читает animals.txt в обратном порядке и выводит до строки с собакой 123 4335 включительно, а затем снова поворачивает в обратную сторону, чтобы восстановить правильный порядок.

Снова, если вам не нужно совпадение в результате, добавьте хвост. (Вы также можете усложнить выражение sed, чтобы отбросить его буфер перед выходом)

.
27
27.01.2020, 19:33

Мой ответ на вопрос в теме, без хранения шаблона во втором файле. Вот мой тестовый файл:

$ cat animals.txt 
cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

GNU SED:

 $ sed '0,/^dog 123 4335$/d' animals.txt 
 cat 13123 23424 
 deer 2131 213132
 bear 2313 21313

Perl:

$ perl -ne 'print unless 1.../^dog 123 4335$/' animals.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313

Вариант Perl с рисунком в файле:

$ cat pattern.txt 
dog 123 4335
$ perl -ne 'BEGIN{chomp($p=(<STDIN>)[0])};print unless 1../$p/;' animals.txt < pattern.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313
4
27.01.2020, 19:33

На практике я, вероятно, большую часть времени использовал бы ответ Aet3miirah, и alexey's answer замечательно подходит для навигации по линиям (также, он работает с less)). ОТОХ, мне действительно нравится другой подход (который является своего рода обратным ответом Жиля :

sed -n '/dog 123 4335/,$p'

При вызове с флагом -n, sed по умолчанию больше не печатает строки, которые он обрабатывает. Затем мы используем 2-адресную форму, которая говорит о применении команды из строки, соответствующей /dog 123 4335/ до конца файла (представленного флагом $). Данная команда представляет собой p, которая печатает текущую строку. Таким образом, это означает "распечатать все строки из одной, соответствующей /дога 123 4335/ до конца"

.
24
27.01.2020, 19:33

с awk :

awk 'BEGIN {getline pattern < "other file"}
   NR == 1, $0 ~ pattern {next}; {print}' < "input file"
11
27.01.2020, 19:33

Если на входе lseekable обычный файл:

С GNU grep :

{ grep  -xFm1 'dog 123 4335' >&2
  cat; } <infile 2>/dev/null >outfile

С sed :

{ sed -n '/^dog 123 4335$/q'
  cat; } <infile >outfile

GNU grep , вызываемый с параметром -m , прекращает ввод при совпадении - и оставляет свой (lseekable) введите fd сразу после точки, в которой было найдено последнее совпадение. Таким образом, вызов grep w / -m1 находит первое вхождение шаблона в файл и оставляет входное смещение точно в нужном месте, чтобы cat мог записать все, что следует за первым совпадением шаблона в файле, на стандартный вывод.

Даже без GNU grep вы можете сделать то же самое с POSIX-совместимым sed - когда sed q uit указано, чтобы оставить его входное смещение там, где оно есть. Однако GNU sed не соответствует стандартам, поэтому приведенное выше, скорее всего, не будет работать с GNU sed , если вы не вызовете его с помощью его -u переключатель.

5
27.01.2020, 19:33

Как вывести все строки после совпадения до конца файла?

По-другому это можно сформулировать так: "Как удалить все строки от 1-й до совпадения (включая)", и это можно sed-записать так:

sed -e '1,/MATCH PATTERN/d'
0
27.01.2020, 19:33

Если вы не возражаете против создания временного файла и у вас есть csplit, это работает:

sh -c 'csplit -sf"$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2

Примечание file1— входной файл, а file2— файл шаблона (, как указано в вопросе ).

Длинная форма приведенной выше команды::

sh -c 'csplit --quiet --prefix="$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2

т. е.

csplit --quiet --prefix="file1_" "file1" "%^$(cat "file2")%+1" && cat "file1_00"

csplitбез приведенного выше флага prefixсоздаст файлxx00(с префиксом xxи суффиксом00). С указанным выше флагом создается файл file1_00. Без флага quietон печатает размер выходного файла (размера результирующего файла ).

1
27.01.2020, 19:33

Теги

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