【问题标题】:How to combine three consecutive lines of text file in sed?如何在sed中合并三行连续的文本文件?
【发布时间】:2015-12-01 23:49:46
【问题描述】:

我有一个文件,它由三行的重复序列组成,我想合并在一起。换句话说,我想将除第三个\n 之外的每一个替换到空间中。例如。我想要转换输入

 href="file:///home/adam/MyDocs/some_file.pdf"
 visited="2013-06-02T20:40:06Z"
 exec="'firefox %u'"
 href="file:///home/adam/Desktop/FreeRDP-WebConnect-1.0.0.167-Setup.exe"
 visited="2013-06-03T08:50:37Z"
 exec="'firefox %u'"
 href="file:///home/adam/Friends/contact.txt"
 visited="2013-06-03T16:01:16Z"
 exec="'gedit %u'"
 href="file:///home/adam/Pictures/Screenshot%20from%202013-06-03%2019:10:36.png"
 visited="2013-06-03T17:10:36Z"
 exec="'eog %u'"

进入

 href="file:///home/adam/MyDocs/some_file.pdf" visited="2013-06-02T20:40:06Z" exec="'firefox %u'"
 href="file:///home/adam/Desktop/FreeRDP-WebConnect-1.0.0.167-Setup.exe" visited="2013-06-03T08:50:37Z" exec="'firefox %u'"
 href="file:///home/adam/Friends/contact.txt" visited="2013-06-03T16:01:16Z" exec="'gedit %u'"
 href="file:///home/adam/Pictures/Screenshot%20from%202013-06-03%2019:10:36.png" visited="2013-06-03T17:10:36Z" exec="'eog %u'"

不幸的是,该文件相当长,所以我不希望将整个文件加载到内存中,也不要将结果写回文件 - 只需将连接的行打印到标准输出中,以便我可以进一步管道。

我知道 可能 sed 可能只是为它工作,但在我诚实地尝试之后,我仍然处于第一阶段;学习曲线对我来说太陡了。 :-(


我做了一个粗略的基准测试,发现sed 变体的速度几乎是原来的两倍。

time awk '{ printf "%s", $0; if (NR % 3 == 0) print ""; else printf " " }' out.txt >/dev/null

real    0m1.893s
user    0m1.860s
sys     0m0.028s

time cat out.txt | sed 'N;N;s/\n/ /g' > /dev/null

real    0m1.360s
user    0m1.264s
sys    0m0.236s

有趣的是:为什么sedawk 需要更多的内核时间?

out.txt 长 200MB,处理器是 Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz,在 Linux-Mint 14 上使用内核 3.8.13-030813-generic。


我需要这个来解析 recently-used.xbel,Cinnamon 中最近打开的文件列表

如果您是为这个特定问题来这里的,这行应该可以帮助您:

xpath -q  -e "//bookmark[*]/@href | //bookmark[*]/@visited | //bookmark[*]/info/metadata/bookmark:applications[1]/bookmark:application[1]/@exec"  recently-used.xbel | sed 's/href="\(.*\)"/"\1"/;N;s/visited="\(.*\)"/\1/;N;s/exec="\(.*\)"/"\1"/;s/\n/ /g' | xargs -n3 whatever-script-you-write 

【问题讨论】:

    标签: sed


    【解决方案1】:

    这个怎么样:

     sed 'N;N;s/\n/ /g' file
    

    【讨论】:

    • 那个“N”代表什么? ...一条线?
    • 可以看到 N 在模式空间中添加了一个新行。您可以在gnu sed manual 中找到更多信息
    【解决方案2】:

    您可以使用awk 轻松完成此操作:

    awk '{ printf "%s", $0; if (NR % 3 == 0) print ""; else printf " " }' file 
    

    基本思想是“打印每一行后跟一个空格,除非每隔三行打印一个换行符”。

    【讨论】:

    • +1 短版:awk '{ printf "%s ", $0 } !(NR%3) { print "" }' inputFile
    • 是的,我有。但我不知道额外的空间是否重要,所以我谨慎行事。
    • @Jaypal 继续打高尔夫球,怎么样:awk 'NR%3{printf "%s ",$0;next}1' file
    • sed 命令几乎快两倍;在测试时,awk 变体的用户时间为 0.188 秒,系统时间为 0.012 秒,sed 变体的用户时间为 0.128 秒,系统时间为 0.30。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多