Как разбить большой файл на две части, по шаблону?
Приведенный пример file.txt
:
ABC
EFG
XYZ
HIJ
KNL
Я хочу разделить этот файл на XYZ
такой, который file1
содержит строки до XYZ
и остальные строки в file2
.
text-processing
sed
awk
split
d.putto
источник
источник
XYZ
линия быть включена в вывод или нет?Ответы:
С
awk
вами можно сделать:Объяснение: Первый
awk
аргумент (out=file1
) определяет переменную с именем файла, которая будет использоваться для вывода при обработке последующего аргумента (largefile
).awk
Программа будет печатать все строки в файл , указанный в переменнойout
({print >out}
). Если шаблонXYZ
будет найден, выходная переменная будет переопределена, чтобы указывать на новый файл ({out="file2}"
), который будет использоваться в качестве цели для печати последующих строк данных.Ссылки:
источник
Это работа для
csplit
:будет
s
принудительно разбивать файл, создавая фрагменты с префиксомf
ixfile
иn
объединяясь в одну цифру, например,file0
и т. д. Обратите внимание, что использование/regex/
будет разбивать до, но не включая совпадающую строкуregex
. Чтобы разделить и включить соответствие строк,regex
добавьте+1
смещение:Это создает два файла,
file0
иfile1
. Если вам абсолютно необходимо, чтобы они были названы,file1
иfile2
вы всегда можете добавить пустой шаблон вcsplit
команду и удалить первый файл:создает
file0
,file1
и ,file2
ноfile0
пуст , так что вы можете безопасно удалить его:источник
С современным
ksh
вот вариант оболочки (т.е. безsed
) одного изsed
основанных ответов выше:И еще один вариант в
ksh
одиночку (то есть также опускаяcat
):(Чистое
ksh
решение кажется довольно производительным; для файла теста объемом 2,4 ГБ требовалось 19–21 с, по сравнению с 39–47 с при использовании подхода на основеsed
/cat
).источник
read
иprint
- вы должны просто позволить ему пойти на вывод своих собственных. Производительность улучшается, если полностью собрать инструментарий AST и собрать всеksh
встроенные модули - для меня странно, чтоsed
на самом деле это не один из них. Но с такими вещами, какwhile <file do
я думаю, тебе не нужноsed
так много ...awk
выступили в своем тесте? И хотя я уверен, чтоksh
, скорее всего, всегда выиграет этот бой, если вы используете GNU, с которымsed
вы не очень честныsed
- GNU-u
nbuffered - это плохой подход к POSIXLY, гарантирующий, что смещение дескриптора остается там, где программа закрывается это - не должно быть необходимости замедлять обычную работу программы - буферизация в порядке - все, чтоsed
нужно сделать, это найти дескриптор, когда закончите. По какой-то причине GNU меняет этот менталитет.while
; печать неявно выполняется как определенный побочный эффект<##
оператора перенаправления. И только соответствующая строка требует печати. (Таким образом, реализация функции оболочки наиболее гибкая для поддержки incl./excl.) Явныйwhile
цикл, который я ожидаю, будет значительно медленнее (но не проверял).head
вместоread
; это только кажется , немного медленнее, но это terser код:{ head -1 <##XYZ ; { read <##"" ;} >file4 ;} <largefile >file3
.С GNU
sed
вы должны использовать-u
переключатель nbuffered. Большинство другихsed
должно просто работать.Чтобы оставить XYZ вне ...
источник
Попробуйте это с помощью GNU sed:
источник
sed -e '1,/XYZ/{w file1' -e 'd}' large_file > file2
Легкий взлом заключается в том, чтобы печатать в STDOUT или STDERR, в зависимости от того, был ли выбран целевой шаблон. Затем вы можете использовать операторы перенаправления оболочки для соответствующего перенаправления вывода. Например, в Perl предполагается, что вызывается входной файл,
f
а два выходных файлаf1
иf2
:Отбрасывая линию, которая соответствует шаблону разделения:
Включая согласованную линию:
В качестве альтернативы, распечатайте на разные дескрипторы файлов:
Отбрасывая линию, которая соответствует шаблону разделения:
Включая согласованную линию:
источник