【问题标题】:Awk (or other) how to force the field number to stay the same?awk(或其他)如何强制字段编号保持不变?
【发布时间】:2015-03-05 03:30:08
【问题描述】:

我有一个包含以下行的输入文件:

A;B;C;D;E;F;G;H;I
1;3312;14.025538;14.617777;0.;0.000000001;253.777023;3.232552;52487.
2;3312;13.206808;13.779518;0.;260.078461;258.954529;3.154804;52487.
3;3312;13.054019;13.491556;0.;256.126221;251.776566;3.247191;52487.
4;3312;12.556334;13.061086;0.;255.570862;254.689224;3.190753;52487.
5;3312;11.719666;11.96375;0.;100.0546;254.258652;3.220166;52487.

我需要始终读取基于 A、C、D 和 F 的字段,在本例中为 $1、$3、$4 和 $6。所以awk很简单:

awk -F";" '{print $1, $3, $4, $6}' input.txt

但是,如果字母的顺序不同,如何得到相同的结果呢?例如,顺序是(我只打印第一行,但下一行的位置也会不同):

A;I;E;H;G;F;C;D;B

我仍然需要始终读取基于 A、C、D 和 F 的字段,但现在它们是 $1、$9、$8 和 $6。而且它们可能再次不同,从输入文件到输入文件。

有没有一种方法可以根据 A、C、D 和 F 对字段进行排序,无论它们的顺序如何,并且忽略所有其他字段,所以我总是会有如下内容:

A;C;D;E
1;14.025538;14.617777;0.000000001
2;13.206808;13.779518;260.078461
3;13.054019;13.491556;256.126221
4;12.556334;13.061086;255.570862
5;11.719666;11.96375;100.0546

【问题讨论】:

  • 我建议 - 如果列具有可区分的模式 - 使用 sed 重新排序输入以使其统一。然后将其通过管道传递给 awk
  • awks 的管道很长,这是有原因的吗?我确信awk 功能强大,只需一个电话即可完成您的任务!你到底想达到什么目的?请公开您的问题,提供示例输入和想要的输出。
  • 正如@gniourf_gniourf 所说,作为开始,您需要向我们展示输入的实际样子。
  • 如果原来 B 是第 2 列,并且输入已更改,则 B 变为第 9 列。如何强制 B 返回为第 2 列?然后我可以将它通过管道传输到 awk。我将尝试获取我的代码示例。为什么我希望 A C D 和 F 分别为 1 美元、3 美元、4 美元和 6 美元,因为我将它通过管道传输到 awk ,这将变为 1 美元、2 美元、3 美元和 4 美元。或者更简单,如何强制 A C D 和 F 成为第 1、2、3 和 4 列并且无论如何总是这样。这样输入的顺序可以改变,但不再重要了。如果你明白我的意思吗?
  • 加上 uno 用于听取建议并添加示例数据和所需的输出。祝你好运。

标签: bash awk


【解决方案1】:

$ awk -F\; -vOFS=\; 'NR==1 {for (i=1; i<=NF; i++) h[$i]=i} {print $h["A"], $h["C"], $h["D"], $h["F"]}'

在输入的第一行,记录从所有列标题到其索引的映射。
之后,在所有规则中,通过标题名称而不是索引来引用字段。

【讨论】:

  • 干得好;添加 -v OFS=\; 以将 output 字段与 ; 实例分开。
  • 我只能说谢谢谢谢!这个 awk 命令会留在我的前 5 名,非常有用。通过这种方式,事情变得容易多了。我只是将 A B C D 和 F 替换为其他变量,事情就这么顺利。是的 mklement0 感谢它使用 -v OFS=\;
猜你喜欢
  • 2016-07-03
  • 1970-01-01
  • 2022-01-11
  • 2016-11-01
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
相关资源
最近更新 更多