我正在 mac 上使用 sed、perl、awk、bash 工作。
我有一个大型 (10GB) 文本文件,其中有 13 个TAB
分隔数据字段(列)。不幸的是,其中一些行有无关的TABs
,所以我想删除多余的整行 TABs
,从而产生不平等的领域。 (我不介意完全丢弃这些行)
我目前所拥有的将字段数写入另一个文件中。
awk -F'\t' '{print NF}' infile > fieldCount
head fieldCount
13
13
10
13
13
13
14
13
13
13
我想构建一个简短的脚本,删除任何多于(或少于)13 个正确字段的行(从原始文件中)。
- 速度很有帮助,因为我必须对多个文件执行此操作
- 一口气完成会很酷
- 我目前正在将 fieldCount 文件移植到 Python 中,尝试逐行加载。
编辑:
有效(13 列)
a b c d e f g h i j k l m
无效(14 列)
a b c d e f g h i j k l m n
答案1
你几乎已经拥有它了:
awk -F'\t' 'NF==13 {打印}'内菲莱 >新文件
而且,如果您使用的是通过击键 (:) )收费的系统之一,您可以将其缩短为
awk -F'\t' 'NF==13'内菲莱 >新文件
要一次扫描多个文件,并实际更改文件(而不仅仅是创建新文件),请识别未使用的文件名(例如scharf
),然后执行循环,如下所示:
对于 f 在列表 做 awk -F'\t' 'NF==13 {print}' "$f" > scharf && mv -f -- scharf "$f" 完毕
这list
可以是一个或多个文件名和/或通配符文件名扩展模式;例如,
for f in blue.data green.data *.dat Orange.data red.data /ultra/violet.dat
该命令用临时文件(仅包含输入文件中的 13 个字段的行)mv
覆盖输入文件(例如, )。 (请确保这是您想要执行的操作,并且要小心。为了安全起见,您可能应该首先备份数据。) 指示覆盖输入文件,即使它已经存在。如果您的任何文件的名称以.blue.data
scharf
-f
mv
--
-
答案2
由于这是一个大文件,因此可能值得使用稍微复杂的工具来提高性能。通常,专用工具比通用工具更快。例如,解决相同的问题cut
往往比grep
哪个更快sed
(awk
另一方面是后来的工具可以做早期工具不能做的事情)。
您想要删除包含 13 个或更多制表符的行,因此:
LC_ALL=C grep -Ev '(␉.*){13}'
或者也许(我不期望有可测量的性能差异)
LC_ALL=C grep -Ev '(␉.*){12}␉'
其中␉
是文字制表符。将语言环境设置为C
不是必需的,但与多字节语言环境相比,某些版本的 GNU grep 可以加快速度。
答案3
和perl
:
perl -F'\t' -anle 'print if @F == 13' file
要就地编辑,请添加-i
选项:
perl -i.bak -F'\t' -anle 'print if @F == 13' file