2013-06-03 3 views
6

Tôi có một tệp, bao gồm một chuỗi lặp lại gồm ba dòng, mà tôi muốn hợp nhất với nhau. Nói cách khác, tôi muốn thay thế tất cả nhưng thứ ba \n vào không gian. Ví dụ. Tôi muốn biến đổi đầu vàoLàm cách nào để kết hợp ba dòng văn bản liên tiếp trong 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'" 

vào

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

Đáng tiếc là các tập tin được khá dài, vì vậy tôi không muốn tải toàn bộ tập tin vào bộ nhớ và không viết thư cho kết quả trở lại tập tin - chỉ cần in các đường nối vào đầu ra tiêu chuẩn để tôi có thể thêm đường ống.

Tôi biết rằng có khả năngsed chỉ có thể làm việc cho nó, nhưng sau khi tôi đã thử nó một cách trung thực, tôi vẫn đang ở hình vuông; đường cong học tập chỉ là quá dốc đối với tôi. :-(


Tôi đã làm một điểm chuẩn thô và tôi phát hiện ra, mà các biến thể sed là gần gấp đôi càng nhanh

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 

Thật là thú vị:. Tại sao không sed yêu cầu nhiều thời gian hạt nhân hơn awk?

Out.txt dài 200MB và bộ xử lý là Intel (R) Core (TM) i7-3610QM CPU @ 2.30GHz trên Linux-Mint 14 với hạt nhân 3.8.13-030813-generic.


tôi cần điều này trong nỗ lực của tôi để phân tích recently-used.xbel, mới khai trương danh sách các file trong Cinnamon

Nếu bạn đến đây để vấn đề cụ thể này, dòng này sẽ giúp bạn:

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 

Trả lời

7

thế nào về điều này:

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

Bạn có thể sử dụng awk để làm điều này khá dễ dàng:

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

Ý tưởng cơ bản là "in mỗi dòng folowed bởi một không gian, trừ khi đó là mỗi dòng thứ ba, trong trường hợp này in một dòng mới".

+1

+1 Phiên bản ngắn hơn: 'awk '{printf"% s ", $ 0}! (NR% 3) {print" "}' inputFile' –

+0

Vâng, tôi đã có. Nhưng tôi không biết liệu không gian thêm có quan trọng không, nên tôi đã thận trọng trước mặt. –

+4

@Jaypal tiếp tục chơi gôn, làm thế nào về: 'awk 'NR% 3 {printf"% s ", $ 0; tiếp theo} 1' file' – Kent