【问题标题】:Deleting columns from a file with awk or from command line on linux使用 awk 或从 linux 上的命令行从文件中删除列
【发布时间】:2011-09-26 06:12:19
【问题描述】:

如何使用awk 从制表符分隔的字段文件中删除某些列?

c1 c2 c3 ..... c60

例如,删除 3 和 29 之间的列。

【问题讨论】:

标签: awk


【解决方案1】:

这就是cut 命令的用途:

cut -f1,2,30- inputfile

默认为制表符。您可以使用-d 开关更改它。

【讨论】:

  • 我必须删除最后一个 - 才能使其在 Ubuntu 中工作。如果我离开它,cut 将打印所有列。有人也遇到过这个问题吗?
  • 它应该打印第一、二和三十列到最后一列(问题中的 60)。如果不是,那是 Ubuntu 中的一个错误!
  • 啊啊,好的。我犯了一个错误。我的错。
  • 如何删除特定的列,例如第三列?
  • @becko 有一个常见的扩展名--complement,它与输入字段编号一样,例如:cut --complement -f3
【解决方案2】:

您可以遍历所有列并过滤掉不需要的列:

awk '{for (i=1; i<=NF; i++) if (i<3 || i>29) printf $i " "; print""}' input.txt

NF 为您提供记录中的字段总数。
对于满足条件的每一列,我们打印该列,后跟一个空格" "


编辑:在约翰尼的评论后更新:

awk -F 'FS' 'BEGIN{FS="\t"}{for (i=1; i<=NF-1; i++) if(i<3 || i>5) {printf $i FS};{print $NF}}' input.txt

这在两个方面得到了改进:

  • 保留原来的分隔符
  • 不在末尾附加分隔符

【讨论】:

  • 您不应该打印制表符 (\t) 而不是空格。他想删除字段,也许不会同时删除标签(如果我理解正确的话)。
  • @johnny:你是对的。我更新了代码,因此它应该正确考虑分隔符。
  • 让我们根据您编辑的答案假设我们要删除列号 2,5,7,8,23,45,67,254,554,488。这会是什么条件?我有近 4000 列的文件。 @奥利弗
【解决方案3】:
awk '{for(z=3;z<=15;z++)$z="";$0=$0;$1=$1}1'

输入

c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21

输出

c1 c2 c16 c17 c18 c19 c20 c21

【讨论】:

  • 这不会删除列。它使它们空白并重新打印...用OP指定的O*FS\t 替换为一个空格,他们没有要求。 明显删除是巧合,需要FSOFS 成为默认\s+。一个非常无用的分隔符并且与 OP 的 \t 不兼容,除非他们的文件巧合地不能有空字段,因为它会将它们压缩成锯齿状的行。任何其他分隔符,例如OP 的\t 提供的输出仍然包含不需要的列,但现在为空。而$0 = $0 是多余的,可能是浪费的。记录的重建记录的方法是$1 = $1
【解决方案4】:

不添加前导或尾随空格的 Perl 'splice' 解决方案:

perl -lane 'splice @F,3,27; print join " ",@F' file

产生输出:

c1 c2 c30 c31

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 2015-09-07
    • 2018-08-18
    • 2018-03-12
    • 2013-10-14
    • 2023-01-26
    • 2013-10-08
    • 2017-07-26
    相关资源
    最近更新 更多