Команда Awk в режиме абзаца, но пропускаются пустые строки
У меня один файл с несколькими элементами <elem>...</elem>
, Мне нужно разделить этот файл на n
файлы с m
каждый элемент (аргумент передается команде awk, которую я использую). Например, если мой исходный файл содержит 40 элементов, я бы хотел разделить его на 3 файла (10 элементов, 13 элементов и 17 элементов).
Проблема в том, что исходный файл имеет элементы с различными структурами.
EDITED AFTER fedorqui comment:
I use as awk command as files I want to get at the end of the process.
That means If I need 3 files with m1, m2 and m3 elements, I will
execute 3 awk with different parameters
Пример ввода (file.txt) (5 элементов)
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
<elem>ccccc
cccc</elem>
Как видите, 1/2/4-й элемент находится в одной строке, 3-й элемент - в 3 строки без пустых строк, а 5-й элемент - в 3 строки с пустой строкой.
Пустые строки между элементами не проблема, но пустые строки внутри элемента терпят неудачу
Пример желаемого результата:
file_1.txt (2 элемента)
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
file_2.txt (2 элемента)
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
file_3.txt (1 элемент)
<elem>ccccc
cccc</elem>
Команда AWK
(Суффикс File - это номер суффикса файла. Например, fileAux_1.txt, fileAux_2.txt...)
Attempt1
awk -v numElems=$1 -v suffixFile=$2 '{
for(i=1;i<=numElems;i++) {
printf "<doc>"$i > "fileAux_" suffixFile".txt"
}
}' RS='' FS='<doc>' file.txt
Работает за исключением пустых строк внутри элемента. Я понимаю, почему это не удается, потому что RS='' говорит awk разделить на пустые строки
Попытка 2
awk -v numElems=$1 -v suffixFile=$2 '{
for(i=1;i<=numElems;i++) {
printf $i > "fileAux_" suffixFile".txt"
}
}' RS='<doc>' FS='<doc>' file.txt
Еще один подход, но он также терпит неудачу
Может кто-нибудь мне помочь?
Заранее спасибо!
1 ответ
Если я правильно понял ваш вызов, вот моя попытка:
$ cat script.sh
#!/bin/bash
awk -v numElems=$1 -v suffixFile=$2 '
/<elem>/{var++}
/<\/elem>/{var--; count++}
{if(count < numElems || (count == numElems && var == 0)) {
print $0 >> "file_"suffixFile".txt"
} else {
print $0
} }' $3
Сценарий в основном отслеживает <elem>
а также </elem>
замыкания с var
и считает пары с count
, Тогда оператор if решает, вставить ли строку в файл или нет. Как только общее количество элементов достигнуто, остальная часть файла возвращается, чтобы вы могли повторить процесс, используя каналы.
Вот пример того, как запустить его с окончательным выводом:
$ ./script.sh 2 1 file.txt | ./script.sh 2 2 | ./script.sh 1 3
$ tail -n +1 file_*
==> file_1.txt <==
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
==> file_2.txt <==
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
==> file_3.txt <==
<elem>ccccc
cccc</elem>