【问题标题】:Different results in awk when using different FS syntax使用不同 FS 语法时 awk 的不同结果
【发布时间】:2016-03-19 18:08:05
【问题描述】:

我有一个包含以下内容的示例文件。

logging.20160309.113.txt.log:  0 Rows successfully loaded.
logging.20160309.1180.txt.log:  0 Rows successfully loaded.
logging.20160309.1199.txt.log:  0 Rows successfully loaded.

我目前熟悉在 awk 中实现字段分隔符语法的两种方法。但是,我目前得到了不同的结果。

我用的时间最长

“FS=”当我的 FS 超过一个字符时的语法。

“-f”标志,当我的 FS 只有一个字符时。

我想了解为什么 FS= 语法会给我带来意想不到的结果,如下所示。不知何故,第一条记录被抛在了后面。

$ head -3 reload_list | awk -F"\.log\:" '{ print $1 }'
awk: warning: escape sequence `\.' treated as plain `.'
awk: warning: escape sequence `\:' treated as plain `:'
logging.20160309.113.txt
logging.20160309.1180.txt
logging.20160309.1199.txt
$ head -3 reload_list |  awk '{ FS="\.log\:" } { print $1 }'
awk: warning: escape sequence `\.' treated as plain `.'
awk: warning: escape sequence `\:' treated as plain `:'
logging.20160309.113.txt.log:
logging.20160309.1180.txt
logging.20160309.1199.txt

【问题讨论】:

    标签: awk rhel


    【解决方案1】:

    您得到不同结果的原因是,在您在 awk 程序中设置 FS 的情况下,它不在 BEGIN 块中。因此,当您设置它时,第一条记录已经被解析为字段(使用默认分隔符)。

    使用-F设置

     $ awk -F"\\.log:" '{ print $1 }' b.txt
     logging.20160309.113.txt
     logging.20160309.1180.txt
     logging.20160309.1199.txt
    

    设置FS解析第一条记录后

    $ awk '{ FS= "\\.log:"} { print $1 }' b.txt
    logging.20160309.113.txt.log:
    logging.20160309.1180.txt
    logging.20160309.1199.txt
    

    在解析任何记录之前设置FS

    $ awk 'BEGIN { FS= "\\.log:"} { print $1 }' b.txt
    logging.20160309.113.txt
    logging.20160309.1180.txt
    logging.20160309.1199.txt
    

    我在 awk 手册中注意到了这一点。如果您之前看到过不同的行为或使用不同的实现,这可以解释原因:

    根据 POSIX 标准,awk 应该表现得好像 每条记录在读取时被拆分为多个字段。在 特别是,这意味着您可以更改 FS 的值 记录被读取,但在任何字段被引用之前。价值 的字段(即它们是如何拆分的)应该反映旧值 FS,不是新的。

    但是,awk 的许多实现不这样做。反而, 他们推迟拆分字段,直到实际引用字段 发生,使用FS当前值!这种行为可以 难以诊断。

    【讨论】:

    • 接受此作为提供手动参考的最佳答案。
    【解决方案2】:

    -f 用于从文件运行脚本。 -FFS 工作方式相同

    $ awk -F'.log' '{print $1}' logs
    logging.20160309.113.txt
    logging.20160309.1180.txt
    logging.20160309.1199.txt
    
    $ awk 'BEGIN{FS=".log"} {print $1}' logs
    logging.20160309.113.txt
    logging.20160309.1180.txt
    logging.20160309.1199.txt
    

    【讨论】:

    • 我知道它不会影响输出,但严格来说,我猜这两种情况下都应该是\\.log
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2023-02-16
    • 2021-06-17
    相关资源
    最近更新 更多