How to combine three consecutive lines of a text file in sed?

I have a file consisting of a repeating sequence of three lines that I want to combine together. In other words, I would like to replace each, but the third \n into space. For instance. I need a conversion input

  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'" 

in

  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'" 

Unfortunately, the file is quite long, so I would prefer not to load the entire file into memory, rather than writing to return the result to the file - just print the concatenated lines to standard output so that I can continue it.

I know that potentially sed might just work for him, but after I gave him an honest try, I am still in first place; The learning curve is too steep for me. :-(


I did some benchmarking, and I found out that the sed option is almost twice as fast.

 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 

and

 time cat out.txt | sed 'N;N;s/\n/ /g' > /dev/null real 0m1.360s user 0m1.264s sys 0m0.236s 

Interesting: why sed takes more kernel time than awk ?

Out.txt has a length of 200 MB, and the processor is an Intel (R) Core i7-3610QM processor with a frequency of 2.30 GHz on Linux-Mint 14 with a kernel 3.8.13-030813.


I need this while trying to parse recently-used.xbel , a list of recently opened files in Cinnamon

If you came here on this particular issue, this line will help you:

 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 
+6
source share
2 answers

how about this:

  sed 'N;N;s/\n/ /g' file 
+7
source

You can use awk to do this quite easily:

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

The main idea is to "print each line, represented by a space, if only every third line, in which case print a new line."

+7
source

Source: https://habr.com/ru/post/946455/


All Articles