【问题标题】:Use awk to print first column, second column and one every 3 columns thereafter and print only rows matching criteria使用 awk 打印第一列、第二列和之后每 3 列打印一个,并且只打印符合条件的行
【发布时间】:2015-08-12 08:01:17
【问题描述】:

我试图让 awk 打印第一列、第二列和之后每 4 列(例如 1、2、6、10 等)。我还想删除第二行,因为这是一个包含不重要内容的标题。最后,我想根据第一列的值(作为字符串向量提供)过滤行。

让我们以这个例子为例,假设我只想要匹配“table”或“chair”的行:

string  number1 junk1   junk2   junk3   number2 junk4   junk5   junk6   number3
junk7   junk8   junk9   junk10  junk11  junk12  junk13  junk14  junk15  junk16
car     7       x1      x5      x9      3       x13     x17     x21     11
table   8       x2      x6      x10     5       x14     x18     x22     2
chair   9       x3      x7      x11     4       x15     x19     x23     6
comb    0       x4      x8      x12     1       x16     x20     x24     10

我想把它作为输出

string  number1 number2 number3
table   8   5   2
chair   9   4   6

谢谢

【问题讨论】:

  • 好的,那么到目前为止你尝试了什么?
  • 我有一个使用 awk 的工作解决方案,它通过管道连接到非常慢的 grep,但不是只使用 awk。我在这里有另一个话题:stackoverflow.com/questions/31950514/…,但被要求提出一个新问题来构建
  • 要匹配的单词列表以什么形式出现?一个文件,或者一个 shell 数组,还是什么?
  • 我从 R 动态调用 awk 代码以使用 data.table 加载结果数据。因此,awk 行是动态生成的。例如,它可能是动态生成的 awk 中的数组。如果拥有 1000+ || 的可能性和可行,下面的答案可能会起作用语句连接在一起。
  • 如果您正在生成代码,那么您可以在BEGIN 块中定义一个类似a["table"]; a["chair"]; 等的数组,然后使用测试$1 in a。但是,如果您已经在使用 R,那么我不确定您为什么要走这条路——使用 R 不是更有意义吗?

标签: awk


【解决方案1】:

如果您的列限制为 10 个

 awk 'BEGIN{OFS="\t"} NR!=2 && /table/ || /chair/ || NR==1{print $1,$2,$6,$10}'

如果列数未知,或者无法枚举,您可以这样做。

 awk 'BEGIN{OFS="\t"} NR!=2 && /table/ || /chair/ || NR==1{line=$1 OFS $2; for(i=6;i<=NF;i+=4)line=line OFS $i; print line}'

也可以将过滤器外化为变量,如

awk -v filter="chair table" 'BEGIN{OFS="\t"} NR==1 || (NR!=2 && (filter ~ $1)) {line=$1 OFS $2; for(i=6;i<=NF;i+=4)line=line OFS $i; print line}'

【讨论】:

  • 很遗憾列数未知,可能有几百个。
  • 第二个完美运行!是否也可以使第一列应与动态变量匹配的变量向量?这样就不必知道或限制为两个?
  • 这适用于动态生成的命令: cmd = sprintf('awk -v filter="%s" \'BEGIN{OFS="\t"} NR==1 || (NR!=2 && (filter ~ $1)) {line=$1 OFS $2; for(i=6;i
  • 当您只想选择以关键字car 开头的行并且您的输入数据包含以carpet 开头的行时,请尝试这样做。
【解决方案2】:
$ awk -v keys='table|chair' 'NR==1 || (NR>2 && $1~"^("keys")$") {out=$1; for (i=2;i<=NF;i+=4) out = out OFS $i; print out}' file
string number1 number2 number3
table 8 5 2
chair 9 4 6

以上假设您的密钥不包含 RE 元字符,如果他们可以编辑您的问题以显示这一点,那么您将需要不同的解决方案。

【讨论】:

    猜你喜欢
    • 2015-11-04
    • 2023-02-04
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多