将多行组合成一行

时间:2010-03-18 04:36:39

标签: vim scripting sed awk

我有一个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 个答案:

答案 0 :(得分:4)

在vim中,您可以使用

执行此操作
:g/<abc/ .,/<\/abc/ join!

通常情况下:join会在加入之前在每行的末尾添加一个空格,但!会抑制该空格。

一般情况下,我建议在Python,Ruby或Perl等语言中使用适当的XML解析库来操作XML文件(我推荐使用Python + ElementTree),但在这种情况下,它很容易使用正则表达式溶液

答案 1 :(得分:4)

在Vim:

  • 第一行的位置
  • qq:开始录制宏
  • gJgJ:在不添加空格的情况下连接下两行
  • j:下去
  • q:停止录制
  • N@q:N =行数(实际上约为所有行的1/3,因为它们会随时压缩)

答案 2 :(得分:1)

$ 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>

答案 3 :(得分:1)

击:

while read s; do echo -n $s; read s; echo -n $s; read s; echo $s; done < file.xml

答案 4 :(得分:1)

您可以录制宏。基本上我要做的是从第一行开头的光标开始。按'qa'(将宏记录到寄存器中)。按下shift-V为直线视觉模式。然后搜索结束标记'// abc'。然后按shift-J加入线。然后你必须将光标移动到下一个标签,可能是'j ^'并按'q'停止录制。然后,您可以使用'@a'重新运行录制,或者如果您愿意,可以指定10000 @ a。如果标签不同或不相同,您只需要更改搜索开关标签的方式或类似内容。

答案 5 :(得分:1)

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>

答案 6 :(得分:0)

不太优雅的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

答案 7 :(得分:0)

你可以这样做:

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

答案 8 :(得分:0)

sed '/<abc/,/<\/abc>/{:a;N;s/\n//g;s|<\/abc>|<\/abc>\n|g;H;ta}'  file

答案 9 :(得分:0)

tr "\n" " "<myfile|sed 's|<\/abc>|<\/abc>\n|g;s/[ \t]*<abc/<abc/g;s/>[ \t]*</></g'

答案 10 :(得分:0)

这应该在ex模式下工作:

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

我应该有额外的空格(或者值之间有一个标签),但你可以根据它是什么来取消它(\ t或\ \ \ \)。

您正在搜索/替换的内容是(pattern1)[enter](pattern2)[enter](pattern3)[enter]并将其替换为(pattern1)(pattern2)(pattern3)[enter]

使用ctrl + v CTRL + m

完成^ M.