
Можно ли использовать функцию split для разделения файла на несколько сегментов, размер каждого из которых зависит от количества совпадений элемента XML?
Например, для XML-разбиения ниже, когда количество встреч "<test xsi:type="update" locale="en_US">
" равно 2
<?xml version="1.0" encoding="UTF-8"?>
<testers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
</testers>
Разделение указанного выше XML-файла должно привести к созданию 2 файлов.
файл1 :
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
и файл 2, содержащий только одну запись:
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
Вот что я пытаюсь сделать:
split -p "<test xsi:type=\"update\" locale=\"en_US\">" test.xml segment
который выводит 4 файла:
сегментаа :
<?xml version="1.0" encoding="UTF-8"?>
<testers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
сегментаб :
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
сегментак :
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
сегментад:
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
</testers>
Можно split
использовать так, как я предлагаю. Файл, который я обрабатываю, имеет размер 40 ГБ, я использую приведенный выше пример, чтобы проиллюстрировать проблему, которую пытаюсь решить.
решение1
Я не думаю, что это возможно с split
. Вы могли бы использовать awk
:
awk '
BEGIN{
fmt="segment%02d" # 2 digits for suffix, zero padded
start="<test xsi:type=\"update\" locale=\"en_US\">"
end="</test>"
}
$0 == start, $0 == end{
if ($0 == start && ++cnt%2==1){ # for every 2nd start element...
fname=sprintf(fmt, fcnt++) # update output filename
}
print $0 > fname # print line, redirect output to fname
}
' test.xml
Это создает два файла segment00
и segment01
:
$ head segment*
==> segment00 <==
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
==> segment01 <==
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>