[英]awk: select first column and value in column after matching word
我有一个.csv,其中每一行对应一个人(第一列)和具有该人可用值的属性。 我想为属性可用的人提取特定属性的名称和值。 该文档的结构如下:
name,attribute1,value1,attribute2,value2,attribute3,value3
joe,height,5.2,weight,178,hair,
james,,,,,,
jesse,weight,165,height,5.3,hair,brown
jerome,hair,black,breakfast,donuts,height,6.8
我想要一个看起来像这样的文件:
name,attribute,value
joe,height,5.2
jesse,height,5.3
jerome,height,6.8
使用这篇较早的帖子,我尝试了几种不同的awk
方法,但仍然无法同时获取第一列和任何具有所需属性值(比如高度)的列。 例如,以下返回所有内容。
awk -F "height," '{print $1 "," FS$2}' file.csv
我可以grep
只有其中包含高度的行,但如果可以的话,我更愿意在一行中完成所有操作。
您可以使用此awk
:
cat attrib.awk
BEGIN {
FS=OFS=","
print "name,attribute,value"
}
NR > 1 && match($0, k "[^,]+") {
print $1, substr($0, RSTART+1, RLENGTH-1)
}
# then run it as
awk -v k=',height,' -f attrib.awk file
name,attribute,value
joe,height,5.2
jesse,height,5.3
jerome,height,6.8
# or this one
awk -v k=',weight,' -f attrib.awk file
name,attribute,value
joe,weight,178
jesse,weight,165
使用您显示的示例,请尝试使用以下awk
代码。 在 GNU awk
中编写和测试。 简单的解释是,使用 GNU awk
并将RS
(记录分隔符)设置为^[^,]*,height,[^,]*
然后根据要求打印 RT 以获得预期的 output。
awk -v RS='^[^,]*,height,[^,]*' 'RT{print RT}' Input_file
一个awk
想法:
awk -v attr="height" '
BEGIN { FS=OFS="," }
FNR==1 { print "name", "attribute", "value"; next }
{ for (i=2;i<=NF;i+=2) # loop through even-numbered fields
if ($i == attr) { # if field value is an exact match to the "attr" variable then ...
print $1,$i,$(i+1) # print current name, current field and next field to stdout
next # no need to check rest of current line; skip to next input line
}
}
' file.csv
注意:这假设输入值(本例中的height
)将与文件中的字段完全匹配(包括相同的大小写)
这会产生:
name,attribute,value
joe,height,5.2
jesse,height,5.3
jerome,height,6.8
我建议使用sed
:
sed -n 's/^\([^,]*\).*\(,height,[^,]*\).*/\1\2/p' file.csv
使用perl 单线:
$ perl -lne '
print "name,attribute,value" if $.==1;
print "$1,$2" if /^(\w+).*(height,\d+\.\d+)/
' file
name,attribute,value
joe,height,5.2
jesse,height,5.3
jerome,height,6.8
awk
在脚本之前的-v
标志之后接受变量值 arguments。 因此,可以使用通用模式将所需属性的名称传递到 awk 脚本中:
awk -v attr=attribute1 ' {} ' file.csv
在脚本内部,传递的变量的值由变量名引用,在本例中为attr
。
您的标准是打印第 1 列,第一列包含名称,对应于所需 header 值的列,以及紧接在该列之后的列(包含匹配值)。
因此,以下脚本允许您找出标题为“attribute1”的列及其下一个邻居:
awk -v attr=attribute1 ' BEGIN {FS=","} /attr/{for (i=1;i<=NF;i++) if($i == attr) col=i;} {print $1","$col","$(col+1)} ' data.txt
结果:
name,attribute1,value1
joe,height,5.2
james,,
jesse,weight,165
jerome,hair,black
另一列(属性 3):
awk -v attr=attribute3 ' BEGIN {FS=","} /attr/{for (i=1;i<=NF;i++) if($i == attr) col=i;} {print $1","$col","$(col+1)} ' awkNames.txt
结果:
name,attribute3,value3
joe,hair,
james,,
jesse,hair,brown
jerome,height,6.8
只需更改所需列的-v attr=
参数的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.