У меня есть файл с около 1000 строк. Мне нужна часть моего файла после строки, которая соответствует моему выражению grep.
То есть:
$ cat file | grep 'TERMINATE' # It is found on line 534
Итак, я хочу файл из строки 535 в строку 1000 для дальнейшей обработки.
Как я могу это сделать?
grep 'TERMINATE' file
grep
стандартный интерфейс ввода для чтения данных, а не узнавать, к какому переключателю обращатьсяgrep
, иsed
, иawk
, иpandoc
, иffmpeg
т. Д., Когда мы хотим прочитать из файла. Это экономит время, потому что нам не нужно изучать новый переключатель каждый раз, когда мы хотим сделать то же самое: читать из файла.grep 'TERMINATE' < file
. Может быть, это делает чтение немного сложнее - но это сценарии оболочки, так что это всегда будет проблемой :)Ответы:
Далее будет напечатана строка соответствия
TERMINATE
до конца файла:Объяснено:
-n
отключает поведение по умолчаниюsed
при печати каждой строки после выполнения сценария на нем,-e
указывает сценарий наsed
,/TERMINATE/,$
это выбор диапазона адресов (строк), означающий, что первая строка соответствуетTERMINATE
регулярному выражению (например, grep) до конца файла ($
) иp
- команда печати, которая печатает текущую строку.Это напечатает от строки, которая следует за соответствующей строкой
TERMINATE
до конца файла:(от ПОСЛЕ соответствующей строки к EOF, НЕ включая соответствующую строку)
Объяснено:
1,/TERMINATE/
это выбор диапазона адресов (строк), означающий первую строку для ввода в 1-ю строку, соответствующуюTERMINATE
регулярному выражению, иd
это команда удаления, которая удаляет текущую строку и переходит к следующей строке. Так как поsed
умолчанию выполняется печать строк, он будет печатать строки послеTERMINATE
конца ввода.Редактировать:
Если вы хотите строки раньше
TERMINATE
:И если вы хотите обе строки до и после
TERMINATE
в 2 разных файлах за один проход:Файлы before и after будут содержать строку с terminate, поэтому для обработки каждого из них вам необходимо использовать:
Edit2:
Если вы не хотите жестко кодировать имена файлов в сценарии sed, вы можете:
Но тогда вы должны избежать
$
значения последней строки, чтобы оболочка не пыталась расширить$w
переменную (обратите внимание, что теперь мы используем двойные кавычки вокруг сценария вместо одинарных кавычек).Я забыл сказать, что новая строка важна после имен файлов в скрипте, так что sed знает, что имена файлов заканчиваются.
Изменить: 2016-0530
Себастьян Клеман спросил: «Как бы вы заменили жестко закодированную
TERMINATE
переменную?»Вы должны сделать переменную для соответствующего текста, а затем сделать это так же, как в предыдущем примере:
использовать переменную для сопоставления текста с предыдущими примерами:
Важными моментами о замене текста переменными в этих случаях являются:
$variablename
), заключенные вsingle quotes
['
], не будут «расширяться», но переменные внутриdouble quotes
["
] будут. Таким образом, вы должны изменить все ,single quotes
чтобы ,double quotes
если они содержат текст , который вы хотите заменить переменную.sed
диапазонах также содержат$
и сразу же следуют буква , как:$p
,$d
,$w
. Они также будут выглядеть как переменные , которые будут расширены, так что вы должны избежать этих$
символов с обратной косой черты [\
] , как:\$p
,\$d
,\$w
.источник
sed -e "1,/$matchtext/d"
не работает, когда$matchtext
происходит в первой строке. Я должен был изменить это наsed -e "0,/$matchtext/d"
.В качестве простого приближения вы можете использовать
который ищет
TERMINATE
и выводит до 100000 строк после этой строки.С man страницы
источник
file
вместо этого вы можете считать следующие строки :grep -A$(cat file | wc -l) TERMINATE file
Инструмент для использования здесь - awk:
Как это работает:
Другие решения могут потреблять много памяти, если вы используете их для очень больших файлов.
источник
cat file | awk 'BEGIN{ found=0} /###/{found=found+1} {if (found<2) print }'
cat
.awk
вполне способен принимать одно или несколько имен файлов в качестве аргументов. См. Также stackoverflow.com/questions/11710552/useless-use-of-catЕсли я правильно понимаю ваш вопрос, вы хотите строки после
TERMINATE
, не включаяTERMINATE
-line.awk
можно сделать это простым способом:Объяснение:
if(found) print
) не будет печатать ничего, с чего можно начать.Это будет печатать все строки , после в
TERMINATE
-LINE.Обобщение:
Пример:
Объяснение:
found
она установлена.found=1
так, чтобы были напечатаны следующие строки. Обратите внимание, что эта проверка выполняется после фактической печати, чтобы исключить начальную строку из результата.Ноты:
BEGIN{found=0}
в начало выражения awk.источник
{if(found) print}
Это немного анти-паттерн в awk, более идиоматично заменять блок простоfound
или,found;
если вам нужен другой фильтр впоследствии.awk '{if(found) print} /TERMINATE/{found=1}' your_file
сawk 'found; /TERMINATE/{found=1}' your_file
, они оба должны делать то же самое.Используйте расширение параметра bash следующим образом:
источник
printf
или убедиться, что вы точно знаете, что передаётеecho
.).grep -A 10000000 'TERMINATE' файл
источник
Есть много способов сделать это с помощью
sed
илиawk
:Это ищет
TERMINATE
в вашем файле и печатает от этой строки до конца файла.Это точно такое же поведение, как и
sed
.Если вам известен номер строки, с которой вы хотите начать печать, вы можете указать его вместе с
NR
(номер записи, который в итоге указывает номер строки):пример
источник
more +7 file
Если по какой-либо причине вы хотите избежать использования sed, следующий текст напечатает соответствие
TERMINATE
до конца файла:и следующее напечатает от следующей строки соответствия
TERMINATE
до конца файла:Чтобы сделать то, что sed может сделать в одном процессе, требуется 2 процесса, и если файл изменяется между выполнением grep и tail, результат может быть непоследовательным, поэтому я рекомендую использовать sed. Кроме того, если файл не содержит
TERMINATE
, 1-я команда терпит неудачу.источник
Альтернативы отличному
sed
ответу от jfgagne, которые не содержат совпадающей строки:awk '/TERMINATE/ {y=1;next} y'
( https://stackoverflow.com/a/18166628 )awk '/TERMINATE/ ? c++ : c'
( https://stackoverflow.com/a/23984891 )perl -ne 'print unless 1 .. /TERMINATE/'
( https://stackoverflow.com/a/18167194 )источник
Это может быть одним из способов сделать это. Если вы знаете, в какой строке файла у вас есть слово grep и сколько строк в вашем файле:
grep -A466 'TERMINATE' файл
источник
grep
даже не требуется; Вы можете просто использоватьtail -n $NUM
, так что это не совсем ответ.sed - гораздо лучший инструмент для работы: файл sed -n '/ re /, $ p'
где re это регулярное выражение
Другой вариант - флаг grea --after-context. Вам нужно ввести число, чтобы закончить на этом, использование wc в файле должно дать правильное значение для остановки. Объедините это с -n и вашим выражением соответствия.
источник
Они будут печатать все строки от последней найденной строки «TERMINATE» до конца файла:
источник
grep
чтобы вы могли набрать его,tail
является расточительным антипаттерном. Поиск соответствия и печать через конец файла (или, наоборот, печать и остановка при первом совпадении) в высшей степени выполняются с помощью обычных, необходимых самих инструментов регулярных выражений. Массивgrep | tail | sed | awk
также сам по себе является массовым бесполезным использованиемgrep
и друзьями .tail
и выполните задачу в более способном инструменте в целом. Во всяком случае, название ясно говорит «первый матч».