在保留计数的同时,根据模式匹配(SED或AWK)移动位置,向文件数据添加标题



我目前正在努力查询,我需要从2个或更多列的文件中获取数据,不仅提取数据,而且根据给定的数据为每列添加标题。以下是文件数据的示例。

,

test_AA.98
test_AA.99+
8 35=Apples
16 35=Pears
test_AA.100
14 35=Apples
12 35=Pears
test_AB.101-
15 35=Banannas

——如果我cat和awk的第一列- cat testfile | awk '{print $1}' -结果

test_AA.98
test_AA.99+
8
16

test_AA.100
14
12
test_AB.101-
15

——如果我cat和walk第二列- cat testfile | awk '{print $2}' -结果为

35=Apples
35=Pears

35=Apples
35=Oranges

35=Banannas

——谁能提供一个解决方案,我可以添加一个标题标题到我的数据基于模式匹配(测试*)到$1的位置,匹配35=*,移动到$2的位置,同时保持计数和值在适当的地方?我想要的结果

Suppliers,  Red=35=Apples, Green=35=Pears, Yellow=35=Banannas

test_AA.98, 0,  0,  0
test_AA.99+,    8,  16, 0
test_AA.100,    14, 12, 0
test_AB.101-,   0,  0,  15

我只找到了一些解决方案来添加标题,但还没有找到在标题下放置正确值的方法。

sed '1iSuppliers, Red=35=Apples, Green=35=Pears, Yellow=35=Banannas' testfile
Suppliers, 35=Apples, 35=Pears, 35=Banannas
test_AA.98
test_AA.99+
8 35=Apples
16 35=Pears

test_AA.100
14 35=Apples
12 35=Oranges
test_AB.101-
15 35=Banannas

多谢! !

你可以从这里开始。

With awkscript:

# set column separator
# r[] - output columns
BEGIN { OFS=", "; r[0]="Suppliers" }
# first pass:
# find name from $2, store for later lookup
# t[] - test if $2 value already seen
# c[] - lookup table for column index by name
FNR==NR && NF==2 && !t[$2]++ { r[++n]=$2; c[$2]=n }
FNR==NR { next }
# second pass:
# line with single field ends previous block
NF==1 {
# print row (or header if first line)
s=r[0]; for(i=1;i<=n;i++) s = s OFS r[i]; print s
# reset columns for subsequent lines
r[0]=$1; for(i=1;i<=n;i++) r[i]=0
next
}
# insert value into appropriate output column
NF==2 { r[c[$2]]=$1 }
# output the final line
END { s=r[0]; for(i=1;i<=n;i++) s = s OFS r[i]; print s }

调用:

awk -f script testfile testfile
对于您的示例输入,这将产生:

Suppliers, 35=Apples, 35=Pears, 35=Banannas
test_AA.98, 0, 0, 0
test_AA.99+, 8, 16, 0
test_AA.100, 14, 12, 0
test_AB.101-, 0, 0, 15

如果你已经知道标题可以取的所有值,并且你想用一些东西作为前缀,或者以特定的顺序显示它们,你可以在BEGIN中适当地初始化r[]c[]。然后删除FNR==NR ...行,调用为awk -f script testfile

$ cat tst.awk
BEGIN {
col2tag[++numCols] = "Suppliers"
OFS = ",t"
}
NF==1 {
rowNr = ++numRows
colNr = 1
}
NF==2 {
if ( $2 in tag2col ) {
colNr = tag2col[$2]
}
else {
colNr = ++numCols
col2tag[colNr] = $2
tag2col[$2] = colNr
}
}
NF {
vals[rowNr,colNr] = $1
}
END {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", col2tag[colNr], (colNr<numCols ? OFS : ORS)
}
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
val = ( (rowNr,colNr) in vals ? vals[rowNr,colNr] : 0 )
printf "%s%s", val, (colNr<numCols ? OFS : ORS)
}
}
}

$ awk -f tst.awk file
Suppliers,      35=Apples,      35=Pears,       35=Banannas
test_AA.98,     0,      0,      0
test_AA.99+,    8,      16,     0
test_AA.100,    14,     12,     0
test_AB.101-,   0,      0,      15

$ awk -f tst.awk file | column -s$'t' -t
Suppliers,     35=Apples,  35=Pears,  35=Banannas
test_AA.98,    0,          0,         0
test_AA.99+,   8,          16,        0
test_AA.100,   14,         12,        0
test_AB.101-,  0,          0,         15

最新更新