Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 检查第n个符号是否为逗号_Bash_Awk_Sed_Text Processing - Fatal编程技术网

Bash 检查第n个符号是否为逗号

Bash 检查第n个符号是否为逗号,bash,awk,sed,text-processing,Bash,Awk,Sed,Text Processing,我的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.yo

我的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 one liner:

awk '{printf "%s%s", (NR>1&&/^[0-9]{10}/?"\n":""),$0}END{print ""}' file
它工作得很好,但检查第10个符号是否为逗号可能会更快

新行字符只能在链接内部使用,链接不能包含逗号


如果您能提供帮助,我将不胜感激。

这里是另一种方法(我假设文件中没有前导行):

测试它:

$ 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

如您所见,我的方法要快得多。

这里是另一种方法(我假设文件中没有前导行):

测试它:

$ 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

正如您所见,我的方法要快得多。

在发布问题时,最好询问如何解决问题,而不是如何实施问题的特定解决方案,因为您提出或得到的解决方案可能不是解决问题的最佳方案

这将是解决您的问题的更自然的方法,而且它恰好比您要求的解决方案更快:

$ 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

在发布问题时,最好询问如何解决问题,而不是如何实施问题的特定解决方案,因为您提出或得到的解决方案可能不是解决问题的最佳方案

这将是解决您的问题的更自然的方法,而且它恰好比您要求的解决方案更快:

$ 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
这可能适用于您(GNU-sed):

一次读两行,如果第二行不包含逗号,则将其连接到第一行。

这可能适用于您(GNU-sed):



一次读两行,如果第二行不包含逗号,则将其连接到第一行。

我猜您拥有的
awk
将比需要计数的
更快,以获得新行。这里每行只有两个
,所以你有一个工作的awk程序,你想要一个更快的?如果这是一个性能优化问题,您应该包括示例输入、当前计时和目标计时。@哈希您的意思是链接部分可能有多个换行符?但第10个字符不是逗号。原始问题的链接:。请注意,如中所述,必须使用
--re interval
开关使其与gawk一起工作。我猜您拥有的
awk
将比需要计数
以获得新行的更快。这里每行只有两个
,所以你有一个工作的awk程序,你想要一个更快的?如果这是一个性能优化问题,您应该包括示例输入、当前计时和目标计时。@哈希您的意思是链接部分可能有多个换行符?但第10个字符不是逗号。原始问题的链接:。请注意,如中所述,必须使用
--re interval
开关使其与gawk一起工作。对于您的10K,这是一个非常好的答案。测试线束和统计数据不少于!:-)。我怀疑性能的巨大改进是由于缓存,因为我在尝试时没有看到任何类似的改进,尝试运行每个脚本3次,然后再查看原始脚本在第一次执行时的运行速度。尽管如此,您生成的输出仍然不正确。@Ed感谢您在我的代码中发现了错误。我已经对它进行了更新,以便它现在可以生成正确的输出。我也更新了时间。非常好的回答你的10公里。测试线束和统计数据不少于!:-)。我怀疑性能的巨大改进是由于缓存,因为我在尝试时没有看到任何类似的改进,尝试运行每个脚本3次,然后再查看原始脚本在第一次执行时的运行速度。尽管如此,您生成的输出仍然不正确。@Ed感谢您在我的代码中发现了错误。我已经对它进行了更新,以便它现在可以生成正确的输出。我还更新了时间安排。@Ed您删除重复测试的想法是正确的(我再次更新了答案)。仍然不如您的版本快。@EdMorton我没有注意到缓存带来的任何改进。以下是在BSD
awk
和GNU
awk
上为和运行的三次。输入文件的创建方式与您和Tom相同。有趣。看起来BSD awk总是使用大约36秒,无论您执行哪个解决方案或执行多少次。谢谢,不客气。请考虑一下,告诉我们你会怎么做。了解脚本的作用非常重要,这样您就可以编写/修改自己的脚本。提示:在手册页中查找
NF
的含义。我已经完成了!NF-当前记录中的字段数awk-F,{printf”%s%s“,(NR>1&&NF>22?RS:”),$0}END{print”“}用于23列awk没有看起来那么难,对不起,我很烦人)@Ed您删除重复测试的想法是正确的(我再次更新了我的答案)。仍然不如您的版本快。@EdMorton我没有注意到缓存带来的任何改进。以下是在BSD
awk
和GNU
awk
上为和运行的三次。输入文件的创建方式与您和Tom相同。有趣。看起来BSD awk总是使用大约36秒,无论您执行哪个解决方案或执行多少次。谢谢,不客气。请考虑一下,告诉我们你会怎么做。了解脚本的作用非常重要,这样您就可以编写/修改自己的脚本。提示:在手册页中查找
NF
的含义。我已经完成了!NF—c中的字段数