Объединение нескольких строк в одну строку - PullRequest
9 голосов
/ 18 марта 2010

У меня есть этот вариант использования 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 строк в файле в формате ввода, как я могу быстро преобразовать это в формат вывода.

Ответы [ 11 ]

4 голосов
/ 18 марта 2010

В vim вы можете сделать это с

:g/<abc/ .,/<\/abc/ join!

Обычно: соединение добавляет пробел в конце каждой строки перед соединением, но ! подавляет это.

В целом, я бы рекомендовал использовать правильную библиотеку XML-разбора на языке, таком как Python, Ruby или Perl, для манипулирования файлами XML (я рекомендую Python + ElementTree), но в этом случае достаточно просто отказаться от использования регулярных выражений решение.

4 голосов
/ 21 марта 2010

В Vim:

  • позиция на первой строке
  • qq: начать запись макроса
  • gJgJ: объединяет следующие две строки без добавления пробелов
  • j: идти вниз
  • q: остановить запись
  • N@q: N = количество строк (на самом деле около 1/3 всех строк, поскольку они уплотняются на ходу)
1 голос
/ 28 марта 2010
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>
1 голос
/ 18 марта 2010

Вы можете записать макрос. По сути, я бы начал с курсора в начале первой строки. Нажмите «qa» (запись макроса в регистр). Нажмите shift-V, чтобы быть линейным визуальным режимом. Затем найдите конечный тег «// abc». Затем нажмите Shift-J, чтобы присоединиться к линиям. Затем вам придется переместить курсор к следующему тегу, возможно, с помощью «j ^» и нажать «q», чтобы остановить запись. Затем вы можете перезапустить запись с помощью '@a' или указать 10000 @ a, если хотите. Если теги различаются или не располагаются сразу после друг друга, вам просто нужно изменить способ поиска открывающих и закрывающих тегов для поиска или что-то в этом роде.

1 голос
/ 18 марта 2010

Bash:

while read s; do echo -n $s; read s; echo -n $s; read s; echo $s; done < file.xml
1 голос
/ 18 марта 2010
$ 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>
0 голосов
/ 24 марта 2010

Это должно работать в режиме ex:

<code>:%s/\(^<abc.*>\)^M^\(.*\)^M^\(^<\/abc>\).*^M/\1\2\3^M/g

У меня должны быть лишние пробелы (или вкладка между значением), но вы можете удалить его в зависимости от того, что это такое (\ t или \ \ \ \).

Здесь вы ищете / заменяете следующее: (pattern1) [enter] (pattern2) [enter] (pattern3) [enter] и замените его на (pattern1) (pattern2) (pattern3) [enter]

^ M делается с помощью ctrl + v CTRL + m

0 голосов
/ 18 марта 2010
tr "\n" " "<myfile|sed 's|<\/abc>|<\/abc>\n|g;s/[ \t]*<abc/<abc/g;s/>[ \t]*</></g'
0 голосов
/ 18 марта 2010
sed '/<abc/,/<\/abc>/{:a;N;s/\n//g;s|<\/abc>|<\/abc>\n|g;H;ta}'  file
0 голосов
/ 18 марта 2010

Вы можете сделать это:

perl -e '$i=1; while(<>){chomp;$s.=$_;if($i%3==0){$s=~s{>\s+<}{><};print "$s\n";$s="";}$i++;}' file
...