Linux 如何通过匹配标题拆分列?
我在想是否有办法通过匹配标题来拆分列 数据如下所示Linux 如何通过匹配标题拆分列?,linux,awk,Linux,Awk,我在想是否有办法通过匹配标题来拆分列 数据如下所示 ID_1 ID_2 ID_3 ID_6 ID_15 value1 0 2 4 7 6 value2 0 4 4 3 8 value3 2 2 3 7 8 我只想获取ID_3和ID_15上的列 ID_3 ID_15 4 6 4 8 3 8 如果我
ID_1 ID_2 ID_3 ID_6 ID_15
value1 0 2 4 7 6
value2 0 4 4 3 8
value3 2 2 3 7 8
我只想获取ID_3和ID_15上的列
ID_3 ID_15
4 6
4 8
3 8
如果我知道列的顺序,awk可以简单地将它分隔开
然而,我有一张很大的桌子,手里只有一张ID列表。我仍然可以使用awk吗?或者在linux中有更简单的方法吗
$cat c.awk
$ cat c.awk
NR == 1 {
for (i=1; i<=NF; ++i) {
if ($i == "ID_3") col_3 = (i + 1)
if ($i == "ID_15") col_15 = (i + 1)
}
print "ID_3", "ID_15"
}
NR > 1 { print $col_3, $col_15 }
$ awk -f c.awk c.txt
ID_3 ID_15
4 6
4 8
3 8
NR==1{
对于(i=1;i1{print$col_3,$col_15}
$awk-f c.awk c.txt
ID_3 ID_15
4 6
4 8
3 8
$cat c.awk
NR==1{
对于(i=1;i1{print$col_3,$col_15}
$awk-f c.awk c.txt
ID_3 ID_15
4 6
4 8
3 8
您可以选择以下方式:
BEGIN {
keys["ID_3"]
keys["ID_15"]
}
NR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in keys) cols[++n] = i
}
{
for (i = 1; i <= n; ++i)
printf "%s%s", $(cols[i]+(NR>1)), (i < n ? OFS : ORS)
}
在处理文件之前,将在keys
数组中设置键,对应于感兴趣的列标题
在第一行,记录包含cols
数组中一个键的所有列号
循环遍历每个COL并将其打印出来,然后是输出字段分隔符OFS或输出记录分隔符ORS,具体取决于它是否是最后一个。
$(cols[i]+(NR>1))
处理第一行之后的行在开始处有一个额外字段的事实,因为NR>1
对于这些行将为true(1),对于第一行将为false(0)。您可以这样做:
BEGIN {
keys["ID_3"]
keys["ID_15"]
}
NR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in keys) cols[++n] = i
}
{
for (i = 1; i <= n; ++i)
printf "%s%s", $(cols[i]+(NR>1)), (i < n ? OFS : ORS)
}
在处理文件之前,将在keys
数组中设置键,对应于感兴趣的列标题
在第一行,记录包含cols
数组中一个键的所有列号
循环遍历每个COL并将其打印出来,然后是输出字段分隔符OFS或输出记录分隔符ORS,具体取决于它是否是最后一个。$(cols[i]+(NR>1))
处理第一行之后的行在开始处有一个额外字段的事实,因为NR>1
对于这些行为true(1),对于第一行为false(0)。请尝试下面的脚本:
#!/bin/sh
file="$1"; shift
awk -v cols="$*" '
BEGIN{
split(cols,C)
OFS=FS="\t"
getline
split($0,H)
for(c in C){
for(h in H){
if(C[c]==H[h])F[i++]=h
}
}
}
{ l="";for(f in F){l=l $F[f] OFS}print l }
' "$file"
在命令行类型中:
[sumit.gupta@rpm01 ~]$ test.sh filename ID_3 ID_5
请尝试以下脚本:
#!/bin/sh
file="$1"; shift
awk -v cols="$*" '
BEGIN{
split(cols,C)
OFS=FS="\t"
getline
split($0,H)
for(c in C){
for(h in H){
if(C[c]==H[h])F[i++]=h
}
}
}
{ l="";for(f in F){l=l $F[f] OFS}print l }
' "$file"
在命令行类型中:
[sumit.gupta@rpm01 ~]$ test.sh filename ID_3 ID_5
输入格式没有很好的定义,但有几种简单的方法,
awk
、perl
和sqlite
(FNR==1) {
nocol=split(col,ocols,/,/) # cols contains named columns
ncols=split("vals " $0,cols) # header line
for (nn=1; nn<=ncols; nn++) colmap[cols[nn]]=nn # map names
OFS="\t" # to align output
for (nn=1; nn<=nocol; nn++) printf("%s%s",ocols[nn],OFS)
printf("\n") # output header line
}
(FNR>1) { # read data
for (nn=1; nn<=nocol; nn++) {
if (nn>1) printf(OFS) # pad
if (ocols[nn] in colmap) { printf("%s",$(colmap[ocols[nn]])) }
else { printf "--" } # named column not in data
}
printf("\n") # wrap line
}
$ nawk -f mycols.awk -v col=ID_3,ID_15 data
ID_3 ID_15
4 6
4 8
3 8
这会在第一行中添加一个虚拟的第一列“VAL”,然后以逗号分隔的方式打印每一行,这是通过对$1
进行看似无意义的赋值来实现的,但这会导致重新计算$0
,将FS(空格/制表符)替换为OFS
(逗号)
使用.once
或.output
将输出发送到文件()。根据需要使用.headers on
或.headers off
。
sqlite非常乐意创建一个未命名的列,因此您不必在标题行的第一列中添加名称,但需要确保所有输入行和格式的列数相同
如果在
.import
过程中出现“预期的X列但发现的Y列”错误,则需要对此数据格式进行一些清理。输入格式没有很好的定义,但有几种简单的方法,awk
,perl
和sqlite
(FNR==1) {
nocol=split(col,ocols,/,/) # cols contains named columns
ncols=split("vals " $0,cols) # header line
for (nn=1; nn<=ncols; nn++) colmap[cols[nn]]=nn # map names
OFS="\t" # to align output
for (nn=1; nn<=nocol; nn++) printf("%s%s",ocols[nn],OFS)
printf("\n") # output header line
}
(FNR>1) { # read data
for (nn=1; nn<=nocol; nn++) {
if (nn>1) printf(OFS) # pad
if (ocols[nn] in colmap) { printf("%s",$(colmap[ocols[nn]])) }
else { printf "--" } # named column not in data
}
printf("\n") # wrap line
}
$ nawk -f mycols.awk -v col=ID_3,ID_15 data
ID_3 ID_15
4 6
4 8
3 8
这会在第一行中添加一个虚拟的第一列“VAL”,然后以逗号分隔的方式打印每一行,这是通过对$1
进行看似无意义的赋值来实现的,但这会导致重新计算$0
,将FS(空格/制表符)替换为OFS
(逗号)
使用.once
或.output
将输出发送到文件()。根据需要使用.headers on
或.headers off
。
sqlite非常乐意创建一个未命名的列,因此您不必在标题行的第一列中添加名称,但需要确保所有输入行和格式的列数相同
如果在
导入过程中出现“预期X列,但发现Y列”错误,则需要对此数据格式进行一些清理。请参阅,例如,请参阅,您不能将用于(f中的f)
若要按顺序迭代,即使索引是整数,也会根据awk实现定期以错误的顺序输出列。此外,千万不要命名变量l
,因为它看起来太像1
,而这不是使用getline
-请参见..不能使用for(f中的f)
即使索引是整数,也要按顺序迭代,这会根据awk实现定期以错误的顺序输出列。此外,千万不要命名变量l
,因为它看起来太像1
,而这不是使用getline
的方式-请看..是的,它有点密集。我已经编辑过添加它n脚本形式。是的,我很懒…我编辑它是为了使用正确的一个谢谢。它看起来简单明了。但是,我正在尝试获得数百个匹配的标题。在脚本中编写标题匹配规则似乎不可行。但是,我有一种感觉。谢谢。是的,它有点密集,不可否认。我编辑是为了在脚本形式中添加它。是的我很懒…我编辑它是为了使用正确的标题谢谢。它看起来简单明了。但是,我正在尝试获取数百个匹配的标题。在脚本中编写标题匹配规则似乎不可行。但是,我有一种感觉。谢谢。谢谢。如果我需要获取数百个匹配的标题呢?至少我从你那里得到了一些想法你的建议。谢谢。谢谢。如果我需要得到数百个匹配的标题呢?至少我从你的建议中得到了一些想法。谢谢。非常感谢。我尝试了第一个awk脚本,它很有效。但是,似乎即使我给出了正确的标题,我也无法定义第一列……对不起,第三列中缺少一个空格在awk脚本中,匿名第一列被命名,修复了!非常感谢。我尝试了第一个awk脚本,它很有效。但是,似乎我可以