Как я могу извлечь заранее определенный диапазон строк из текстового файла в Unix? - PullRequest
470 голосов
/ 17 сентября 2008

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

Кто-нибудь знает команду Unix (или серию команд), чтобы извлечь все строки из файла, скажем, между строками 16224 и 16482, а затем перенаправить их в новый файл?

Ответы [ 22 ]

708 голосов
/ 17 сентября 2008
sed -n '16224,16482p;16483q' filename > newfile

Из руководства sed :

p - Распечатайте пространство шаблона (к стандартному выводу). Эта команда обычно используется только в сочетании с параметром командной строки -n.

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

q - Выход sed без обработки каких-либо команд или ввода. Обратите внимание, что текущее пространство шаблона печатается, если автоматическая печать не отключена с опцией -n.

и

Адреса в сценарии sed могут быть в любой из следующих форм:

номер Указание номера строки будет соответствовать только этой строке на входе.

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

197 голосов
/ 17 сентября 2008
sed -n '16224,16482 p' orig-data-file > new-file

Где 16224,16482 - номер начальной и конечной строки включительно. Это 1-индексированный. -n подавляет эхо ввода как вывода, что вам явно не нужно; числа указывают диапазон строк, на которых должна работать следующая команда; команда p выводит соответствующие строки.

81 голосов
/ 17 сентября 2008

Довольно просто, используя голову / хвост:

head -16482 in.sql | tail -258 > out.sql

с использованием sed:

sed -n '16482,16482p' in.sql > out.sql

с использованием awk:

awk 'NR>=10&&NR<=20' in.sql > out.sql
28 голосов
/ 17 сентября 2008

Вы можете использовать 'vi' и затем следующую команду:

:16224,16482w!/tmp/some-file

В качестве альтернативы:

cat file | head -n 16482 | tail -n 258

РЕДАКТИРОВАТЬ: - Просто чтобы добавить объяснение, вы используете head -n 16482 для отображения первых 16482 строк, затем используйте tail -n 258 , чтобы получить последние 258 строк из первого вывода ,

22 голосов
/ 14 января 2014

Существует еще один подход с awk:

awk 'NR==16224, NR==16482' file

Если файл огромен, может быть хорошо до exit после прочтения последней требуемой строки. Таким образом, он не будет читать следующие строки без необходимости:

awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file
17 голосов
/ 17 сентября 2008
perl -ne 'print if 16224..16482' file.txt > new_file.txt
8 голосов
/ 17 сентября 2008
 # print section of file based on line numbers
 sed -n '16224 ,16482p'               # method 1
 sed '16224,16482!d'                 # method 2
5 голосов
/ 17 сентября 2008
cat dump.txt | head -16224 | tail -258

должен сделать свое дело. Недостатком этого подхода является то, что вам нужно выполнить арифметику, чтобы определить аргумент для tail и учесть, хотите ли вы, чтобы между ними была добавлена ​​конечная строка.

5 голосов
/ 17 сентября 2008

sed -n '16224,16482p' < dump.sql

3 голосов
/ 17 сентября 2008

Я собирался опубликовать трюк с головой / хвостом, но на самом деле я бы просто запустил emacs. ; -)

  1. esc - x go-line ret 16224
  2. mark ( ctrl - пробел )
  3. esc - x goto-line ret 16482
  4. * 1027 ESC * ш

открыть новый выходной файл, ctl-y сохранить

Давайте посмотрим, что происходит.

...