【问题标题】:Arithmetic operations with awk用 awk 进行算术运算
【发布时间】:2016-07-25 00:52:34
【问题描述】:

我正在尝试使用 awk 来修改此文件的第一列:

0.947250   0.000000 0.001000 0.015500 0.177000 0.806500
0.971700   0.000000 0.000100 0.005000 0.102900 0.892000
0.985701   0.000000 0.000000 0.001200 0.054795 0.944006
0.994251   0.000000 0.000000 0.000000 0.022998 0.977002
0.996850   0.000000 0.000000 0.000000 0.012599 0.987401
0.998150   0.000000 0.000000 0.000000 0.007399 0.992601
0.998800   0.000000 0.000000 0.000000 0.004800 0.995200
0.999250   0.000000 0.000000 0.000000 0.003000 0.997000
0.999450   0.000000 0.000000 0.000000 0.002200 0.997800
0.999750   0.000000 0.000000 0.000000 0.001000 0.999000

我需要将第一列中的值转换为 1 值,而其他列保持不变。我正在尝试命令

awk '{ x=1.-$1; print x,$2,$3,$4,$5,$6}' in_file > out_file

但这给了我

1  0.000000 0.001000 0.015500 0.177000 0.806500
1  0.000000 0.000100 0.005000 0.102900 0.892000
1  0.000000 0.000000 0.001200 0.054795 0.944006
1  0.000000 0.000000 0.000000 0.022998 0.977002
1  0.000000 0.000000 0.000000 0.012599 0.987401
1  0.000000 0.000000 0.000000 0.007399 0.992601
1  0.000000 0.000000 0.000000 0.004800 0.995200
1  0.000000 0.000000 0.000000 0.003000 0.997000
1  0.000000 0.000000 0.000000 0.002200 0.997800
1  0.000000 0.000000 0.000000 0.001000 0.999000

我做错了什么?

我也尝试过不同的说法,但都没有奏效。截图如下:

更新

看起来问题出在我的awk 版本(我在OSX 10.9.5 上使用awk 版本20070501)而不是语法。事实上,我下载了gawk,现在一切似乎都很好。所以问题应该是为什么我的 awk 似乎不能正常工作......

【问题讨论】:

  • 我无法使用 GNU awk、OS X 上的默认 awk 或来自 NetBSD 的 nawk 重现此问题。 awk 在什么操作系统上使用?
  • @Kusalananda 我在 OSX 上使用默认的 awk:版本 20070501,OSX 10.9.5
  • 我有相同的awk,但在 OS X 10.11.5 上。我无权访问 OS X 10.9.5,因此无法对此进行测试...但是您的命令绝对可以在我的 Mac 上按照您想要的方式运行。
  • @Kusalananda 我安装了 gawk 现在它可以工作了!
  • @EdMorton 通过显式提供小数点来尝试将 int 提升为 float 是相当普遍的做法。他遇到了1-$1 的问题(获取整数1),所以他尝试了1.-$1。这有什么随机性?这就像说$string + 0 强制一种语言将$string 解释为一个数字。一个完全合理的尝试。

标签: macos awk


【解决方案1】:

默认情况下awk 使用print 命令打印所有字段。以下就足够了:

awk '{$1=1-$1;print}' in_file > out_file

编辑:基于[ @ed-morton's ]对[ this ]的评论回答:

如果语言环境不是 C(或 POSIX,应该相同),有时 awk 可能会以意想不到的方式运行。

LC_ALL_OLD="$LC_ALL"
LC_ALL=C
awk '{$1=1-$1;print}' in_file > out_file
LC_ALL="$LC_ALL_OLD"

参考

[ What does LC_ALL=C do? ]

【讨论】:

  • 谢谢。出于某种原因,如果我使用 awk,它就不起作用。但如果我使用 gawk,它会完美运行。
  • @valerio92 : 当你尝试上面的错误是什么?
  • @valerio92 : 你能发布ls -l $(which gawk) 和ls -l $(which awk) 的结果吗
  • lrwxr-xr-x 1 Valerio admin 29B 23 Lug 11:25 /usr/local/bin/gawk@ -> ../Cellar/gawk/4.1.1/bin/gawk(哪个傻瓜); -rwxr-xr-x 1 root wheel 106K 28 Giu 2014 /usr/bin/awk*(哪个 awk)
  • @valerio92 : 我怀疑这是 awk 的错误,现在你已经安装了 gawk 你可以完全删除 awk 并将 awk 链接到 gawk
【解决方案2】:

您的 awk 行为正确,问题是您的语言环境设置当前使用 , 而不是 . 作为小数点,这与您的数据相矛盾,因此字符串 0.5 将被视为 0数字运算,因为预期的数字是0,5。

用途:

LC_ALL=C awk '{$1=1-$1}1' in_file > out_file

改为(或在您的环境中导出 LC_ALL=C 以将该设置用于所有命令)并参阅 https://unix.stackexchange.com/a/87763/133219 了解有关区域设置的信息和 LC_ALL。

【讨论】:

    【解决方案3】:

    我解决了在我的 mac (OSX 10.9.5) 上安装 gawk 的问题。由于某种原因,我的 awk 实现无法正常工作。

    gawk '{ x=1.-$1; print x,$2,$3,$4,$5,$6}' in_file > out_file
    

    现在的输出是正确的:

    0.05275 0.000000 0.001000 0.015500 0.177000 0.806500
    0.0283 0.000000 0.000100 0.005000 0.102900 0.892000
    0.014299 0.000000 0.000000 0.001200 0.054795 0.944006
    0.005749 0.000000 0.000000 0.000000 0.022998 0.977002
    0.00315 0.000000 0.000000 0.000000 0.012599 0.987401
    0.00185 0.000000 0.000000 0.000000 0.007399 0.992601
    0.0012 0.000000 0.000000 0.000000 0.004800 0.995200
    0.00075 0.000000 0.000000 0.000000 0.003000 0.997000
    0.00055 0.000000 0.000000 0.000000 0.002200 0.997800
    0.00025 0.000000 0.000000 0.000000 0.001000 0.999000
    

    还有不同的说法:

    (Installing gawk on mac)

    【讨论】:

    • @Ed Morton x=1-$1 也不起作用,并且 1.=1.0。我认为这很清楚。另外,如果我的表达是如此毫无意义,为什么它会完全像我在 gawk 中想要的那样工作?
    • @valerio92:见[ this ]
    【解决方案4】:

    同意 cmets 认为语言环境可能是罪魁祸首,OP 可以使用“。”的各种语言环境中的任何一种。不是小数分隔符。例如,

    LC_ALL=it_IT.UTF-8 ./foo.sh;cat out_file
    

    给了我(相同版本的 BSD-awk):

    1 0.000000 0.001000 0.015500 0.177000 0.806500
    1 0.000000 0.000100 0.005000 0.102900 0.892000
    1 0.000000 0.000000 0.001200 0.054795 0.944006
    1 0.000000 0.000000 0.000000 0.022998 0.977002
    1 0.000000 0.000000 0.000000 0.012599 0.987401
    1 0.000000 0.000000 0.000000 0.007399 0.992601
    1 0.000000 0.000000 0.000000 0.004800 0.995200
    1 0.000000 0.000000 0.000000 0.003000 0.997000
    1 0.000000 0.000000 0.000000 0.002200 0.997800
    1 0.000000 0.000000 0.000000 0.001000 0.999000
    

    同时

    LC_ALL=en_US.UTF-8 ./foo.sh;cat out_file
    

    给我

    0.05275 0.000000 0.001000 0.015500 0.177000 0.806500
    0.0283 0.000000 0.000100 0.005000 0.102900 0.892000
    0.014299 0.000000 0.000000 0.001200 0.054795 0.944006
    0.005749 0.000000 0.000000 0.000000 0.022998 0.977002
    0.00315 0.000000 0.000000 0.000000 0.012599 0.987401
    0.00185 0.000000 0.000000 0.000000 0.007399 0.992601
    0.0012 0.000000 0.000000 0.000000 0.004800 0.995200
    0.00075 0.000000 0.000000 0.000000 0.003000 0.997000
    0.00055 0.000000 0.000000 0.000000 0.002200 0.997800
    0.00025 0.000000 0.000000 0.000000 0.001000 0.999000
    

    进一步阅读:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 2018-10-10
      • 2011-05-07
      • 2013-02-27
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      相关资源
      最近更新 更多