是否可以在 awk 中使用两个不同的字段分隔符并将两者的值存储在变量中?

Posted

技术标签:

【中文标题】是否可以在 awk 中使用两个不同的字段分隔符并将两者的值存储在变量中?【英文标题】:Is it possible to use two different Field Separators in awk and store values from both in variables? 【发布时间】:2012-08-16 08:53:54 【问题描述】:

我想我的一般问题是,是否可以给 awk 一个字段分隔符,将其中一个标记存储在一个变量中,然后给 awk 另一个字段分隔符,并将其中一个标记存储在第二个变量中,然后打印出两个变量值?似乎变量存储了对 $nth 标记的引用,而不是值本身。

我想到的具体例子或多或少遵循这种形式:Animal, species class

Cat, Felis catus MAMMAL
Dog, Canis lupus familiaris MAMMAL
Peregrine Falcon, Falco peregrinus AVIAN
...

并且您希望它输出如下内容:

Cat MAMMAL
Dog MAMMAL
Peregrine Falcon AVIAN
...

你想要的是符合形式的东西:Animal 类

用 括起来的东西意味着它可以有任意数量的空格。

我最初的想法是我会有这样的东西:

cat test.txt | awk 'FS=","; animal=$1; FS=" "; class=$NF; print animal, class; > animals.txt

我希望变量“animal”存储逗号左侧的内容,而“class”存储该动物的类类型,如 MAMMAL 等。但最终发生的是只有最后使用的应用了字段分隔符,因此对于名称中包含空格的内容(例如 Peregrine Falcon 等),这会中断。

所以它看起来像

Cat, MAMMAL
Dog, MAMMAL
Peregrine AVIAN

【问题讨论】:

【参考方案1】:

一种使用awk的方式:

awk -F, ' n = split($2,array," "); printf "%s, %s\n", $1, array[n] ' file.txt

结果:

Cat, MAMMAL
Dog, MAMMAL
Peregrine Falcon, AVIAN

【讨论】:

呵呵,和我的一样,只是反过来。 +1。 :) @ghoti:有趣的视角! +1 Split 非常简洁,我不知道这一点,这绝对是我一直在寻找的东西。谢谢!【参考方案2】:

您始终可以在 awk 脚本中使用split()。您还可以操作导致整行被重新解析的字段。例如,这会在您的问题中得到结果:

awk 'cl=$NF; split($0,a,", "); printf("%s, %s\n", a[1], cl)' test.txt

【讨论】:

【参考方案3】:

awk 的字段分隔符可以是任何正则表达式,但在这种情况下使用记录分隔符可能更容易,将其设置为 [,\n] 将在您想要的字段之间交替:

awk -v RS='[,\n]' 'NR % 2  printf("%s, ", $0)  NR % 2 == 0  print $NF '

所以偶数字段完整输出,奇数字段只输出最后一个字段。

【讨论】:

【参考方案4】:
paste -d, <(cut -d, -f1 input.txt) <(awk 'print $NF' input.txt)
cut第一栏 awk获取最后一列 paste他们在一起

输出:

Cat,MAMMAL
Dog,MAMMAL
Peregrine Falcon,AVIAN

【讨论】:

以上是关于是否可以在 awk 中使用两个不同的字段分隔符并将两者的值存储在变量中?的主要内容,如果未能解决你的问题,请参考以下文章

在 awk 中打印匹配的字段分隔符

SELinux系列(十七)—awk命令使用详解

SELinux系列(十七)—awk命令使用详解

awk文本处理工具

二.AWK内置变量

如何使用 sed/awk 替换逗号分隔字符串中的第 n 列/字段?