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

时间:2012-08-21 02:14:02

标签: string bash parsing awk

我想我的一般问题是,是否可以给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} class

将某些内容括在{}中意味着它可以包含任意数量的空格。

我最初的想法是我会有这样的事情:

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

4 个答案:

答案 0 :(得分:6)

使用awk的一种方式:

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

结果:

Cat, MAMMAL
Dog, MAMMAL
Peregrine Falcon, AVIAN

答案 1 :(得分:3)

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

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

答案 2 :(得分:3)

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

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

因此,偶数字段将完整输出,奇数字段仅输出最后一个字段。

答案 3 :(得分:2)

paste -d, <(cut -d, -f1 input.txt) <(awk '{print $NF}' input.txt)
  • cut第一栏
  • awk获取最后一栏
  • paste他们在一起

输出:

Cat,MAMMAL
Dog,MAMMAL
Peregrine Falcon,AVIAN