2013-06-03 8 views
6

Ho un file, che consiste in una sequenza ripetuta di tre righe, che voglio unire insieme. In altre parole, mi piacerebbe sostituire tutti tranne il terzo \n nello spazio. Per esempio. Mi piacerebbe l'ingresso trasformataCome combinare tre righe consecutive di file di testo in sed?

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

Purtroppo il file è piuttosto lungo, quindi preferirei non caricare l'intero file in memoria e di non scrivere di provocare nuovamente dentro file - basta stampare le linee concatenate nello standard output in modo da poterla canalizzare ulteriormente.

so che potenzialmentesed potrebbe solo lavorare per esso, ma dopo che avevo dato una prova onesta, io sono ancora al punto di partenza; la curva di apprendimento è troppo ripida per me. :-(


ho fatto un'analisi comparativa di massima e ho scoperto, che la variante sed è quasi due volte più veloce

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 

e

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

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

E 'interessante:. Perché sed richiede più tempo del kernel rispetto a awk?

Il file out.txt è lungo 200 MB e il processore è Intel (R) Core (TM) i7-3610QM CPU @ 2.30 GHz su Linux-Mint 14 con kernel 3.8.13-030813-generico.


ho bisogno di questo nel mio sforzo di analizzare il recently-used.xbel, l'elenco file aperti di recente nel Cannella

Se sei arrivato qui per questo problema specifico, questa linea dovrebbe aiutare:

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 

risposta

7

come su questo:

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

È possibile utilizzare awk per fare questo abbastanza facilmente:

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

L'idea di base è "stampare ogni linea folowed da uno spazio, a meno che non capita tutti i terza linea, nel qual caso la stampa di un ritorno a capo".

+1

+1 Versione più breve: 'awk '{printf"% s ", $ 0}! (NR% 3) {print" "}' inputFile' –

+0

Sì, l'ho avuto. Ma non sapevo se lo spazio extra contava, quindi ho sbagliato sul lato della cautela. –

+4

@Jaypal continua a giocare a golf, che ne dite di: 'awk 'NR% 3 {printf"% s ", $ 0; successivo} 1' file' – Kent

Problemi correlati