【问题标题】:not getting sort output in awk在 awk 中没有得到排序输出
【发布时间】:2012-11-02 14:32:48
【问题描述】:

我正在使用 Aho、Kernighan 的书“AWK 编程语言”。 在第 20 页,他们提供了一个在我的系统上无法运行的程序。

emp.data 是

Beth 4.00 0
Dan 3.75  0
Kathy 4.00 10
Mark 5.00 20
Mary  5.50 22
Susie  4.25 18

他们给出的程序是

awk '{ printf("%6.2f  %s\n" , $2*$3, $0) }' emp.data | sort

他们给出的输出是

但我的输出是

0.00  Beth 4.00 0
  0.00  Dan 3.75  0
100.00  Mark 5.00 20
121.00  Mary  5.50 22
 40.00  Kathy 4.00 10
 76.50  Susie  4.25 18

那么发生了什么?

【问题讨论】:

  • 把那本书扔掉,因为它很旧而且不是很好。 Get Effective Awk Programming, 第三版 由 Arnold Robbins 代替。例如,他们上面的 printf 语法是错误的。话虽如此,如果这是它产生的输出,那么您的“awk”版本就有很大问题。 awk --version 告诉你什么?如果您的 awk 没有损坏,那么您必须在输入文件中隐藏控制字符。
  • 这本书是一颗宝石,请坚持下去:)

标签: awk


【解决方案1】:
  1. 您的 awk 已损坏或您的输入中有控制字符。
  2. 您的 printf 语法错误(但仍会产生正确的输出)

为了避免“2”:printf 是一个内置的语言结构,而不是一个函数。当你这样做时:

printf("%s",foo)

您不是在调用带有 2 个参数的 printf 函数,而是在调用带有 1 个参数的 printf 内置函数,该参数是从 "(" "%s" "、"foo" 和 ")" 构造的。正确的语法很简单:

printf "%s",foo

但是您可以在其中任何一个周围加上括号,它不会增加任何价值,但也不会破坏它。这些中的任何一个都将以相同的方式“工作”:

printf ("%s"),foo
printf "%s",(foo)
printf ("%s"),(foo)
printf (((((((((("%s",foo))))))))))

更重要的是,尽管上面的“1”点是:您告诉 awk 生成格式为:

"%6.2f ...."

这意味着前导数字应在左侧最多填充 2 个前导空格,但您的输出在第一行没有前导空格。这会影响您的“排序”,但由于给出了字符串,这里还有更多事情要做:

 2
10

无论您是进行数字排序还是字母排序都没有关系,因为 2 在数字上小于 10,但空格在数字上也小于 1,因此结果应该是相同的。

但是,您发布的输出暗示您的排序是按字母顺序排序的,“100”小于“40”,这不是排序的工作方式。即使在您的语言环境中以某种方式按字母顺序大于“1”,也无法解释为什么您会得到相当于:

 2
10
 3

在您的输出中,即有时它将空间视为少于一次,而其他时间则视为更多。

由于您的 awk 显然产生了错误的输出,因此您的 awk 或输入文件肯定存在问题,因此我认为您的排序工具也不太可能存在问题。

如果您需要帮助调试问题,请尝试这些命令并发布结果:

$ awk '{ printf "%6.2f\n" , $2*$3 }' emp.data
  0.00
  0.00
 40.00
100.00
121.00
 76.50

$ awk '{ printf "%6.2f\n" , $2*$3 }' emp.data | sort
  0.00
  0.00
 40.00
 76.50
100.00
121.00

我还有另一个想法 - 如果您搞砸了 awk 输出的复制/粘贴,那么可能是语言环境问题。尝试这样做:

export LC_ALL=C

然后再次运行命令(排序时不带“-n”)。

【讨论】:

  • 嗨,Ed,是的,在我发出命令 export LC_ALL=C 之后,我在没有 -n 选项的情况下工作了 sort... 但你可能是对的,我搞砸了复制粘贴。如果你查看我的输出,这些数字并不像书中的输入那样相互低于……无论如何,我使用这本书的原因是因为它有练习。我通过练习更好地学习新材料。我有你提到的另一本书,但它似乎没有任何练习.......
  • 好的,是的,是混乱的复制/粘贴让我认为您的 awk 已损坏或输入已损坏。您需要找出最适合您的语言环境设置。通常 C 语言环境提供的惊喜最少,但有时您需要不同的设置来获得本地货币格式(例如“.”与“,”)。就像我提到的那样,运行 sort -n 不是答案,修复你的语言环境设置才是。
  • 写了 Robbins 的书 - 查看示例程序部分。它有关于如何实现各种 UNIX 实用程序的示例和其他各种示例。只需尝试实现这些并用本书检查您的答案。
  • 好的,埃德,我会调查的
【解决方案2】:

最后尝试sort -n,进行数字排序。默认排序会将 10 放在 2 之前。

【讨论】:

  • sort -n 不是答案。如果您的 awk 生成的输出按照您告诉它的默认格式输出,那么字母排序就可以正常工作。
【解决方案3】:

他们假设按数字排序,您的排序似乎默认为按字母顺序。

查看您的排序命令行选项,看看是否可以将其设为数字​​。

【讨论】:

  • 约翰,是的,我必须使用 -n 选项
  • 不,您的问题与排序无关。使用 sort -n 可以解决真正的问题,即您的 awk 应该生成的前导空格在排序输入中不存在。
猜你喜欢
  • 2021-01-24
  • 1970-01-01
  • 2022-07-28
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多