选择 awk 中的列丢弃相应的 header
selecting columns in awk discarding corresponding header
如何在一些处理后正确 select awk 中的列。我的文件在这里:
cat foo
A;B;C
9;6;7
8;5;4
1;2;3
我想添加带有行号的第一列,然后提取结果的一些列。例如,让我们获取新的第一列(行号)和第三列。这样:
awk -F';' 'FNR==1{print "linenumber;"[=12=];next} {print FNR-1,,}' foo
给我这个意想不到的输出:
linenumber;A;B;C
1 9 7
2 8 4
3 1 3
但预期是(注意 B 现在是第三列,因为我们将行号添加为第一列):
linenumber;B
1;6
2;5
3;2
[修复和修订]
为什么要在 header 中打印 [=14=]
(完整记录)?而且,如果您只想在输出中显示两列,为什么要打印 3(FNR-1
、</code> 和 <code>
)?最后,您的输出字段分隔符是空格而不是预期的 ;
的原因很简单……您没有指定输出字段分隔符 (OFS
)。您可以使用命令行变量赋值 (OFS=\;
) 执行此操作,如下面的第二个和第三个版本所示,但也可以使用 -v
选项 (-v OFS=\;
) 或 BEGIN
block (BEGIN {OFS=";"}
) 随心所欲(这3种方法有区别,但在这里不重要)。
[编辑]:最后查看通用解决方案。
如果您要保留的字段是输入文件的第二个字段(B
列),请尝试:
$ awk -F\; 'FNR==1 {print "linenumber;" ; next} {print FNR-1 ";" }' foo
linenumber;B
1;6
2;5
3;2
或
$ awk -F\; 'FNR==1 {print "linenumber",; next} {print FNR-1,}' OFS=\; foo
linenumber;B
1;6
2;5
3;2
注意,只要你不想保留输入文件的第一个字段(</code>),你也可以用行号覆盖它:</p>
<pre><code>$ awk -F\; '{=FNR==1?"linenumber":FNR-1; print ,}' OFS=\; foo
linenumber;B
1;6
2;5
3;2
最后,这是一个更通用的解决方案,您可以向其中传递要打印的输入文件的列索引列表(本例中为 1 和 3):
$ awk -F\; -v cols='1;3' '
BEGIN { OFS = ";"; n = split(cols, c); }
{ printf("%s", FNR == 1 ? "linenumber" : FNR - 1);
for(i = 1; i <= n; i++) printf("%s", OFS $(c[i]));
printf("\n");
}' foo
linenumber;A;C
1;9;7
2;8;4
3;1;3
要获得预期的输出,请使用:
$ awk 'BEGIN {
FS=OFS=";"
}
{
print (FNR==1?"linenumber":FNR-1),$(FNR==1?3:1)
}' file
输出:
linenumber;C
1;9
2;8
3;1
要添加带有行号的列并提取第一列和最后一列,请使用:
$ awk 'BEGIN {
FS=OFS=";"
}
{
print (FNR==1?"linenumber":FNR-1),,$NF
}' file
本次输出:
linenumber;A;C
1;9;7
2;8;4
3;1;3
如何在一些处理后正确 select awk 中的列。我的文件在这里:
cat foo
A;B;C
9;6;7
8;5;4
1;2;3
我想添加带有行号的第一列,然后提取结果的一些列。例如,让我们获取新的第一列(行号)和第三列。这样:
awk -F';' 'FNR==1{print "linenumber;"[=12=];next} {print FNR-1,,}' foo
给我这个意想不到的输出:
linenumber;A;B;C
1 9 7
2 8 4
3 1 3
但预期是(注意 B 现在是第三列,因为我们将行号添加为第一列):
linenumber;B
1;6
2;5
3;2
[修复和修订]
为什么要在 header 中打印 [=14=]
(完整记录)?而且,如果您只想在输出中显示两列,为什么要打印 3(FNR-1
、</code> 和 <code>
)?最后,您的输出字段分隔符是空格而不是预期的 ;
的原因很简单……您没有指定输出字段分隔符 (OFS
)。您可以使用命令行变量赋值 (OFS=\;
) 执行此操作,如下面的第二个和第三个版本所示,但也可以使用 -v
选项 (-v OFS=\;
) 或 BEGIN
block (BEGIN {OFS=";"}
) 随心所欲(这3种方法有区别,但在这里不重要)。
[编辑]:最后查看通用解决方案。
如果您要保留的字段是输入文件的第二个字段(B
列),请尝试:
$ awk -F\; 'FNR==1 {print "linenumber;" ; next} {print FNR-1 ";" }' foo
linenumber;B
1;6
2;5
3;2
或
$ awk -F\; 'FNR==1 {print "linenumber",; next} {print FNR-1,}' OFS=\; foo
linenumber;B
1;6
2;5
3;2
注意,只要你不想保留输入文件的第一个字段(</code>),你也可以用行号覆盖它:</p>
<pre><code>$ awk -F\; '{=FNR==1?"linenumber":FNR-1; print ,}' OFS=\; foo
linenumber;B
1;6
2;5
3;2
最后,这是一个更通用的解决方案,您可以向其中传递要打印的输入文件的列索引列表(本例中为 1 和 3):
$ awk -F\; -v cols='1;3' '
BEGIN { OFS = ";"; n = split(cols, c); }
{ printf("%s", FNR == 1 ? "linenumber" : FNR - 1);
for(i = 1; i <= n; i++) printf("%s", OFS $(c[i]));
printf("\n");
}' foo
linenumber;A;C
1;9;7
2;8;4
3;1;3
要获得预期的输出,请使用:
$ awk 'BEGIN {
FS=OFS=";"
}
{
print (FNR==1?"linenumber":FNR-1),$(FNR==1?3:1)
}' file
输出:
linenumber;C
1;9
2;8
3;1
要添加带有行号的列并提取第一列和最后一列,请使用:
$ awk 'BEGIN {
FS=OFS=";"
}
{
print (FNR==1?"linenumber":FNR-1),,$NF
}' file
本次输出:
linenumber;A;C
1;9;7
2;8;4
3;1;3