Как я могу извлечь предопределенный диапазон строк из текстового файла в Unix?
410568 просмотра
22 ответа
У меня есть дамп SQL ~ 23000 строк, содержащий несколько баз данных. Мне нужно извлечь определенный раздел этого файла (то есть данные для одной базы данных) и поместить его в новый файл. Я знаю номера начала и конца строки нужных мне данных.
Кто-нибудь знает команду Unix (или серию команд), чтобы извлечь все строки из файла, скажем, между строками 16224 и 16482, а затем перенаправить их в новый файл?
Автор: Adam J. Forster Источник Размещён: 17.05.2019 03:06Ответы (22)
677 плюса
sed -n '16224,16482p;16483q' filename > newfile
Из руководства пользователя sed :
p - Распечатайте пространство шаблона (к стандартному выводу). Эта команда обычно используется только в сочетании с параметром командной строки -n.
n - Если автоматическая печать не отключена, напечатайте пространство шаблона, затем, независимо от этого, замените пространство шаблона следующей строкой ввода. Если входных данных больше нет, sed выходит без обработки каких-либо команд.
q - Выход
sed
без обработки каких-либо дополнительных команд или ввода. Обратите внимание, что текущее пространство шаблона печатается, если автоматическая печать не отключена с опцией -n.
Автор: boxxar Размещён: 17.09.2008 01:42Адреса в сценарии sed могут быть в любой из следующих форм:
номер Указание номера строки будет соответствовать только этой строке на входе.
Диапазон адресов можно указать, указав два адреса, разделенных запятой (,). Диапазон адресов совпадает со строками, начиная с которых совпадает первый адрес, и продолжается до совпадения второго адреса (включительно).
192 плюса
sed -n '16224,16482 p' orig-data-file > new-file
Где 16224,16482 - номер начальной и конечной строки включительно. Это 1-индексированный. -n
подавляет эхо ввода как вывод, который вам явно не нужен; числа указывают диапазон строк, на которых должна работать следующая команда; команда p
печатает соответствующие строки.
78 плюса
Довольно просто, используя голову / хвост:
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
Автор: manveru
Размещён: 17.09.2008 01:46
25 плюса
Вы можете использовать 'vi' и затем следующую команду:
:16224,16482w!/tmp/some-file
В качестве альтернативы:
cat file | head -n 16482 | tail -n 258
РЕДАКТИРОВАТЬ: - Просто чтобы добавить объяснение, вы используете head -n 16482 для отображения первых 16482 строк, а затем с помощью tail -n 258, чтобы получить последние 258 строк из первого вывода.
Автор: Mark Janssen Размещён: 17.09.2008 01:4220 плюса
Есть еще один подход с awk
:
awk 'NR==16224, NR==16482' file
Если файл огромен, это может быть полезно exit
после прочтения последней требуемой строки. Таким образом, он не будет без необходимости читать файл до конца:
awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file
Автор: fedorqui
Размещён: 14.01.2014 04:30
13 плюса
8 плюса
# print section of file based on line numbers
sed -n '16224 ,16482p' # method 1
sed '16224,16482!d' # method 2
Автор: Cetra
Размещён: 17.09.2008 01:42
5 плюса
5 плюса
cat dump.txt | head -16224 | tail -258
должен сделать свое дело. Недостатком этого подхода является то, что вам нужно выполнить арифметику, чтобы определить аргумент для tail и учесть, хотите ли вы, чтобы между ними была добавлена конечная строка или нет.
Автор: JP Lodine Размещён: 17.09.2008 01:493 плюса
Быстро и грязно:
head -16428 < file.in | tail -259 > file.out
Вероятно, не лучший способ сделать это, но это должно работать.
Кстати: 259 = 16482-16224 + 1.
Автор: jan.vdbergh Размещён: 17.09.2008 01:442 плюса
Я собирался опубликовать трюк с головой / хвостом, но на самом деле я бы просто запустил Emacs. ;-)
- esc- xGoto-Line ret16224
- отметка ( ctrl- space)
- esc- xGoto-Line ret16482
- esc-w
откройте новый выходной файл, ctl-y сохраните
Давайте посмотрим, что происходит.
Автор: sammyo Размещён: 17.09.2008 01:492 плюса
Я хотел бы использовать:
awk 'FNR >= 16224 && FNR <= 16482' my_file > extracted.txt
FNR содержит номер записи (строки) строки, читаемой из файла.
Автор: Paddy3118 Размещён: 01.01.2013 06:512 плюса
Я написал программу на Haskell, которая называется Splitter, которая делает именно это: прочитайте мою публикацию в блоге .
Вы можете использовать программу следующим образом:
$ cat somefile | splitter 16224-16482
И это все, что нужно сделать. Вам понадобится Haskell для его установки. Просто:
$ cabal install splitter
И вы сделали. Я надеюсь, что вы найдете эту программу полезной.
Автор: Robert Massaioli Размещён: 25.07.2013 10:432 плюса
Даже мы можем сделать это, чтобы проверить в командной строке:
cat filename|sed 'n1,n2!d' > abc.txt
Например:
cat foo.pl|sed '100,200!d' > abc.txt
Автор: Chinmoy Padhi
Размещён: 05.02.2014 06:41
2 плюса
Используя ruby:
ruby -ne 'puts "#{$.}: #{$_}" if $. >= 32613500 && $. <= 32614500' < GND.rdf > GND.extract.rdf
Автор: Carl Blakeley
Размещён: 21.05.2015 12:23
1 плюс
Я написал небольшой скрипт bash, который вы можете запустить из командной строки, при условии, что вы обновляете свой PATH, чтобы включить его каталог (или вы можете поместить его в каталог, который уже содержится в PATH).
Использование: $ pinch filename start-line end-line
#!/bin/bash
# Display line number ranges of a file to the terminal.
# Usage: $ pinch filename start-line end-line
# By Evan J. Coon
FILENAME=$1
START=$2
END=$3
ERROR="[PINCH ERROR]"
# Check that the number of arguments is 3
if [ $# -lt 3 ]; then
echo "$ERROR Need three arguments: Filename Start-line End-line"
exit 1
fi
# Check that the file exists.
if [ ! -f "$FILENAME" ]; then
echo -e "$ERROR File does not exist. \n\t$FILENAME"
exit 1
fi
# Check that start-line is not greater than end-line
if [ "$START" -gt "$END" ]; then
echo -e "$ERROR Start line is greater than End line."
exit 1
fi
# Check that start-line is positive.
if [ "$START" -lt 0 ]; then
echo -e "$ERROR Start line is less than 0."
exit 1
fi
# Check that end-line is positive.
if [ "$END" -lt 0 ]; then
echo -e "$ERROR End line is less than 0."
exit 1
fi
NUMOFLINES=$(wc -l < "$FILENAME")
# Check that end-line is not greater than the number of lines in the file.
if [ "$END" -gt "$NUMOFLINES" ]; then
echo -e "$ERROR End line is greater than number of lines in file."
exit 1
fi
# The distance from the end of the file to end-line
ENDDIFF=$(( NUMOFLINES - END ))
# For larger files, this will run more quickly. If the distance from the
# end of the file to the end-line is less than the distance from the
# start of the file to the start-line, then start pinching from the
# bottom as opposed to the top.
if [ "$START" -lt "$ENDDIFF" ]; then
< "$FILENAME" head -n $END | tail -n +$START
else
< "$FILENAME" tail -n +$START | head -n $(( END-START+1 ))
fi
# Success
exit 0
Автор: Nerdfighter
Размещён: 10.12.2014 05:06
1 плюс
Это может работать для вас (GNU sed):
sed -ne '16224,16482w newfile' -e '16482q' file
или воспользоваться bash:
sed -n $'16224,16482w newfile\n16482q' file
Автор: potong
Размещён: 10.08.2015 01:00
1 плюс
Я хотел сделать то же самое из скрипта, использующего переменную, и достиг этого, поместив кавычки вокруг переменной $, чтобы отделить имя переменной от p:
sed -n "$first","$count"p imagelist.txt >"$imageblock"
Я хотел разделить список на отдельные папки, нашел начальный вопрос и ответил на полезный шаг. (команда split не является опцией для старой ОС, на которую я должен перенести код).
Автор: KevinY Размещён: 28.10.2017 09:350 плюса
Работа с ключами -n в ответах. Вот другой способ, если вы склонны.
cat $filename | sed "${linenum}p;d";
Это делает следующее:
- передать содержимое файла (или подать текст так, как вы хотите).
- sed выбирает данную строку, печатает ее
- Для удаления строк требуется d, иначе sed будет предполагать, что все строки будут в конечном итоге напечатаны. т. е. без d вы получите все строки, напечатанные выбранной строкой, напечатанные дважды, потому что у вас есть часть $ {linenum} p, запрашивающая ее печать. Я почти уверен, что -n в основном делает то же самое, что и d здесь.
0 плюса
Поскольку речь идет об извлечении строк текста из текстового файла, я приведу особый случай, когда вы хотите извлечь все строки, которые соответствуют определенному шаблону.
myfile content:
=====================
line1 not needed
line2 also discarded
[Data]
first data line
second data line
=====================
sed -n '/Data/,$p' myfile
Напечатает строку [Данные] и остальные. Если вы хотите, чтобы текст из строки 1 соответствовал шаблону, введите: sed -n '1, / Data / p' myfile. Кроме того, если вы знаете два шаблона (лучше быть уникальными в вашем тексте), как начальная, так и конечная линия диапазона могут быть указаны с совпадениями.
sed -n '/BEGIN_MARK/,/END_MARK/p' myfile
Автор: Kemin Zhou
Размещён: 14.02.2018 10:52
0 плюса
Стоя на плечах boxxar, мне нравится это:
sed -n '<first line>,$p;<last line>q' input
например
sed -n '16224,$p;16482q' input
В $
означает «последняя строка», так что первая команда делает sed
печать всех строк , начиная с линии 16224
и вторая команда делает sed
бросить курить после печати линии 16428
. (Добавление 1
к q
-range в растворе boxxar по - видимому, не требуется.)
Мне нравится этот вариант, потому что мне не нужно указывать номер конечной строки дважды. И я измерил, что использование $
не оказывает вредного влияния на производительность.
-3 плюса
Я думаю, что это может быть полезным решением. Если имя таблицы «person», вы можете использовать sed, чтобы получить все строки, необходимые для восстановления таблицы.
sed -n -e '/DROP TABLE IF EXISTS.*`person `/,/UNLOCK TABLES/p' data.sql > new_data.sql
Основываясь на этом ответе , в котором отсутствует «DROP TABLE IF EXIST» для таблицы, которую вы восстанавливаете, и вам нужно удалить несколько строк в нижней части нового файла перед его использованием, чтобы предотвратить удаление следующей таблицы.
Подробную информацию также можно найти здесь
Автор: dvergur Размещён: 06.10.2016 03:20Вопросы из категории :
- unix Эквивалент Windows «хороший»
- unix Использование X Window X Window Server через VPN
- unix Как вы делаете нечувствительный к регистру поиск с использованием модификатора шаблона, используя меньше?
- unix Удалить все, кроме самых последних файлов X в Bash
- unix Проверьте, существует ли каталог в сценарии оболочки
- command-line Как отправить файл в виде вложения электронной почты с помощью командной строки Linux?
- command-line Каков наилучший способ разбора аргументов командной строки?
- command-line Есть ли замена для cat в Windows?
- command-line Как я могу извлечь предопределенный диапазон строк из текстового файла в Unix?
- command-line Как очистить прокрутку в экранной команде?
- sed Как удалить первую строку текстового файла с помощью сценария bash / sed?
- sed Избегайте строки для шаблона замены sed
- sed Используя sed, как вы печатаете первые 'N' символов строки?
- sed upper- to lower-case using sed
- text-processing Как заменить $ {} заполнителей в текстовом файле?
- text-processing Удалить пустые строки в текстовом файле с помощью grep
- text-processing Добавить строку префикса в начало каждой строки
- text-processing Python: как обходить блоки строк