У меня есть этот вариант использования XML-файла с входом как
Input:
<abc a="1">
<val>0.25</val>
</abc>
<abc a="2">
<val>0.25</val>
</abc>
<abc a="3">
<val>0.35</val>
</abc>
...
Output:
<abc a="1"><val>0.25</val></abc>
<abc a="2"><val>0.25</val></abc>
<abc a="3"><val>0.35</val></abc>
Я имею вокруг 200K строк в файле в Формате ввода, как я могу быстро преобразовать это в выходной формат.
В vim вы можете сделать это с помощью
:g/<abc/ .,/<\/abc/ join!
Обычно: join добавит пробел в конце каждой строки перед объединением, но !
подавляет это.
В общем, я бы рекомендовал использовать подходящую библиотеку синтаксического анализа XML на таком языке, как Python, Ruby или Perl, для управления XML-файлами (я рекомендую Python + ElementTree), но в этом случае это достаточно просто, чтобы обойтись без регулярного выражения. решение.
Вы можете сделать это:
perl -e '$i=1; while(<>){chomp;$s.=$_;if($i%3==0){$s=~s{>\s+<}{><};print "$s\n";$s="";}$i++;}' file
Bash:
while read s; do echo -n $s; read s; echo -n $s; read s; echo $s; done < file.xml
Вы можете записать макрос. По сути, я бы начал с курсора в начале первой строки. Нажмите «qa» (записывает макрос в регистр). Нажмите Shift-V, чтобы перейти в линейный визуальный режим. Затем найдите конечный тег '// abc'. Затем нажмите shift-J, чтобы соединить линии. Затем вам нужно будет переместить курсор к следующему тегу, возможно, с помощью 'j ^', и нажать 'q', чтобы остановить запись. Затем вы можете перезапустить запись с помощью '@a' или указать 10000 @ a, если хотите. Если теги разные или расположены не сразу друг за другом, вам просто нужно изменить способ нахождения открывающих и закрывающих тегов для поиска или чего-то в этом роде.
неэлегантная однострочная программа perl, которая должна сделать этот трюк, хотя и не особенно быстро.
cat file | perl -e '
$x=0;
while(<>){
s/^\s*(\S*(?:\s+\S+)*)\s*$/$1/g;
print;
$x++;
if($x==3){
print"\n";
$x=0;
}
}' > output
tr "\n" " "<myfile|sed 's|<\/abc>|<\/abc>\n|g;s/[ \t]*<abc/<abc/g;s/>[ \t]*</></g'
В Vim:
qq
: начать запись макроса gJgJ
: присоединяется к следующим двум строк без пробелов j
: перейти вниз q
: остановить запись N @ q
: N = количество строк (фактически около 1/3 всех строк, поскольку они сжато на ходу) $ awk '
/<abc/ && NR > 1 {print ""}
{gsub(" +"," "); printf "%s",$0}
' file
<abc a="1"> <val>0.25</val></abc>
<abc a="2"> <val>0.25</val></abc>
<abc a="3"> <val>0.35</val></abc>
sed '/<abc/,/<\/abc>/{:a;N;s/\n//g;s|<\/abc>|<\/abc>\n|g;H;ta}' file
Это должно работать в режиме ex:
:% s / \ (^
У меня должны быть лишние пробелы (или табуляция между значениями), но вы можете удалить их в зависимости от того, что это (\ t или \ \ \ \ ).
То, что вы ищете / заменяете, это (шаблон1) [ввод] (шаблон2) [ввод] (шаблон3) [ввод] и заменяет его на (шаблон1) (шаблон2) (шаблон3) [ввод]
^ M выполняется с помощью ctrl + v CTRL + m
sed '/^<abc/{N;N;s/\n\| //g}'
# remove \n or "space"
# Result
<abca="1"><val>0.25</val></abc>
<abca="2"><val>0.25</val></abc>
<abca="3"><val>0.35</val></abc>