我的CSV文件包含
等列start_time,end_time,link
1407233497,1407233514,http://s.youtube.com/stream_204?event=streamingstats&fmt=n
1407233498,1407233515,http://s.youtube.com/stream_204?event=cenjreaecnjcd
mingstats&fmt=n
1407233499,1407233516,http://s.youtube.com/stream_204?event=weedwcecd
有时链接包含新行,我想删除它们。我怎样才能从最终输出变为新线:
1407233497,1407233514,http://s.youtube.com/stream_204?event=streamingstats&fmt=n
1407233498,1407233515,http://s.youtube.com/stream_204?event=cenjreaecnjcdmingstats&fmt=n
1407233499,1407233516,http://s.youtube.com/stream_204?event=weedwcecd
我被提议用这个awk单行:
awk '{printf "%s%s", (NR>1&&/^[0-9]{10}/?"\n":""),$0}END{print ""}' file
效果很好,但是检查第10个符号是逗号会更快吗?
新行字符只能在链接中使用,链接不能包含逗号
我非常感谢你的帮助
答案 0 :(得分:4)
在发布问题以询问如何解决问题而不是如何实现问题的特定解决方案时,这是最好的,因为您提出或给出的解决方案可能不是解决问题的最佳解决方案。
这将是解决您问题的更自然的方式,它恰好比您要求的解决方案更快:
$ awk -F, '{printf "%s%s",(NR>1&&NF>2?RS:""),$0} END{print ""}' file
1407233497,1407233514,http://s.youtube.com/stream_204?event=streamingstats&fmt=n
1407233498,1407233515,http://s.youtube.com/stream_204?event=cenjreaecnjcdmingstats&fmt=n
1407233499,1407233516,http://s.youtube.com/stream_204?event=weedwcecd
使用@TomFenechs 242M样本输入文件:
$ time awk '{printf "%s%s", (NR>1&&/^[0-9]{10}/?"\n":""),$0}END{print ""}' file > kent.out
real 0m17.542s
user 0m16.738s
sys 0m0.530s
$ time awk 'BEGIN{FS=OFS=","}NR>1&&NF>2{print a,b}NF>2{a=$1OFS$2;b=$3;next}{b=b$0}END{print a,b}' file > tom.out
real 0m13.826s
user 0m13.213s
sys 0m0.374s
$ time awk -F, '{printf "%s%s",(NR>1&&NF>2?RS:""),$0} END{print ""}' file > ed.out
real 0m10.785s
user 0m10.030s
sys 0m0.467s
答案 1 :(得分:1)
这是你可以做到的另一种方式(我假设文件中没有前导线):
BEGIN { FS = OFS = "," }
NF>2 { if (NR>1) print a, b; a = $1 OFS $2; b = $3; next }
{ b = b $0 }
END { print a, b }
测试出来:
$ awk -f join.awk file
1407233497,1407233514,http://s.youtube.com/stream_204?event=streamingstats&fmt=n
1407233498,1407233515,http://s.youtube.com/stream_204?event=cenjreaecnjcdmingstats&fmt=n
1407233499,1407233516,http://s.youtube.com/stream_204?event=weedwcecd
我在一个更大的文件中比较了我的方法与你的方法的速度:
$ cat file
1407233497,1407233514,http://s.youtube.com/stream_204?event=streamingstats&fmt=n
1407233498,1407233515,http://s.youtube.com/stream_204?event=cenjreaecnjcd
mingstats&fmt=n
1407233499,1407233516,http://s.youtube.com/stream_204?event=weedwcecd
$ for i in {1..20}; do cat file file > tmp && mv tmp file; done
$ du -h file
242M file
$ time awk 'BEGIN{FS=OFS=","}NF>2{if(NR>1)print a,b;a=$1OFS$2;b=$3;next}{b=b$0}END{print a,b}' file > /dev/null
real 0m13.551s
user 0m13.458s
sys 0m0.069s
$ time awk --re-interval '{printf "%s%s", (NR>1&&/^[0-9]{10}/?"\n":""),$0}END{print ""}' file > /dev/null
real 0m23.438s
user 0m23.331s
sys 0m0.066s
如您所见,我的方法要快得多。
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed ':a;$!N;/\n[^,]*$/s/\n//;ta;P;D' file
一次读取2行,如果第2行不包含逗号,则将其加入第一行。