删除不超过或少于“N”个字段的行?

删除不超过或少于“N”个字段的行?

我正在 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 个正确字段的行(从原始文件中)。

  1. 速度很有帮助,因为我必须对多个文件执行此操作
  2. 一口气完成会很酷
  3. 我目前正在将 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.datascharf-fmv---

答案2

由于这是一个大文件,因此可能值得使用稍微复杂的工具来提高性能。通常,专用工具比通用工具更快。例如,解决相同的问题cut往往比grep哪个更快sedawk另一方面是后来的工具可以做早期工具不能做的事情)。

您想要删除包含 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

相关内容