Как объединить три последовательные строки текстового файла в sed?

у меня есть файл, который состоит из повторяющейся последовательности из трех строк, которые я хочу объединить. Другими словами, Я хотел бы заменить каждый, кроме третьего 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", ; 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

интересно: почему sed требуется больше времени ядра, чем awk?

выход.txt имеет длину 200 МБ, а процессор-Intel(R) Core (TM) i7-3610QM CPU @ 2.30 GHz на 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="(.*)"/""/;N;s/visited="(.*)"//;N;s/exec="(.*)"/""/;s/n/ /g' | xargs -n3 whatever-script-you-write 

2 ответов


Как насчет этого:

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

можно использовать awk сделать это довольно легко:

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

основная идея "печатать каждую строку folowed пробел, если не каждый третьей линии, в этом случае печать строки".