我有一个包含3列和7000行的tsv文件。它看起来像这样:
1341234jh34h123h abc 1
23k4j123j4123h4h abc 1
123j41j234j234jj bbb 1
1234jj1324j123j4 ccc 1
2134j1234j1234jj bbb 1
1324j123j4123j41 abc 1
132j412j34j1234j ddd 1
12j34j1234j4j234 abc 1
12j34j234j123j43 abc 1
123j412j341234jj abc 1
123j4j234j132j4j abc 1
123k41k234123l4l bbb 1
2k134k2134k23k4k abc 2
132k4k132k423k4k ddd 1
k234k123k4k34k34 bbb 1
23k4k34k3k43k43k abc 1
l234k34l3l43;3;4 abc 1
k234k23k42k342k3 bbb 1
q,wmeqwjneqkwjen ddd 1
llqkweqweqjwejqw bbb 1
我的目标是:取出第二列,对其进行排序并在tsv文件中返回唯一值。
我在终端上写的代码是:cut -f 2 input.tsv | sort | uniq > output_final.tsv
在终端(note that the file has 7000 rows
中运行此操作需要花费很长时间。如果您只是在上面提供的20行数据中使用上述代码,那么它将非常快速地完成。)
然而,如果我以一种天真的方式做到这一点,就像下面这样,它会很快完成。
cut -f 2 input.tsv > output1.tsv
然后
sort output1.tsv > output2.tsv
uniq output2.tsv > output_final.tsv
那么为什么cut -f 2 input.tsv | sort | uniq > output_final.tsv
代码会永远运行?我写错了吗?
BIG UPDATE:所以我做了time
@paxdiablo建议的事情。有趣的是,我发现了
time (cut -f 2 input.tsv >/dev/null)
real 0m0.017s
user 0m0.015s
sys 0m0.002s
time (cut -f 2 input.tsv | sort >/dev/null)
real 0m0.025s
user 0m0.021s
sys 0m0.006s
time (cut -f 2 input.tsv | sort | uniq >/dev/null)
real 0m0.027s
user 0m0.026s
sys 0m0.008s
因此,这些工作需要很少的时间。但是当我运行cut -f 2 input.tsv | sort >/dev/null
时,终端就像下面那样挂在那里而根本没有返回任何内容:
chinegro $ > cut -f 2 input.tsv | sort >/dev/null
通常,当作业完成时,终端应该是这样的:
chinegro $ > cut -f 2 input.tsv | sort >/dev/null
output blablablalblalblalblalba
chinegro $ >
答案 0 :(得分:2)
管道不应该产生太大的影响。
我要做的第一件事是通过运行以下命令来查看导致问题的组件:
time ( cut -f 2 input.tsv >/dev/null )
time ( cut -f 2 input.tsv | sort >/dev/null)
time ( cut -f 2 input.tsv | sort | uniq >/dev/null)
每次几次并记录时间。
然后你可能想问a suitable site :-)关于如何最好地完成你想做的工作的问题,而不是假设cut
,sort
和{ {1}}将是必要的。很多人通过陈述他们正在使用的工具来不必要地限制他们的解决方案空间。您应该声明只是问题,并且如果绝对需要,则仅限制解决方案空间。
首先,您可以使用uniq
放弃uniq
,甚至可能有更好的方式使用不同的工具,例如:
sort -u
并且,在您更新后:
awk '{keys[$2] = 1} END {for (key in keys) { print key } }' input.tsv
你可以看到它耗费了大约三十分之一秒(用户+ sys = 0.034s)的CPU时间。
因此,您可能在原始命令本身中遇到了错误。如果它没有返回到长时间的提示,那通常表示您已将输入文件名留下,例如:
time (cut -f 2 input.tsv | sort | uniq >/dev/null)
real 0m0.027s
user 0m0.026s
sys 0m0.008s
并且cut -f 2 | sort
将永远等待,直到您输入一些行,然后按 CTRL-D 指示文件结束(您可以通过输入 CTRL-D来测试此行当它正在运行并查看提示是否返回时。)
所以我建议你检查一下你的实际命令,特别是考虑到最后一个人使用cut
作为输入文件。这是错误的,如果它是一个错字,你应该仔细检查你向我们展示的其他命令是你正在使用的实际的。
答案 1 :(得分:0)
在我的笔记本电脑上,您对7000行的命令是立即执行的,但由于cut -f 2
无法按预期工作,因此无效。这段代码很快就可以了:
while read a b c ; do echo "$b" ; done < input.tsv | sort | uniq >| output_final.tsv
最后>|
代表覆盖。