【问题标题】:AWK to print field $2 first, then field $1AWK 先打印字段 $2,然后打印字段 $1
【发布时间】:2013-03-13 22:08:24
【问题描述】:

这是输入(样本):

name1@gmail.com|com.emailclient.account
name2@msn.com|com.socialsite.auth.account

我正在努力实现这一目标:

Emailclient name1@gmail.com
Socialsite name2@msn.com

如果我像这样使用 AWK:

cat foo | awk 'BEGIN{FS="|"} {print $2 " " $1}'

它通过在字段 2 的顶部覆盖字段 1 来混淆输出。

任何提示/建议?谢谢。

【问题讨论】:

    标签: unix awk


    【解决方案1】:

    也许您的文件包含 CRLF 终止符。每行后跟 \r\n。

    awk 识别 $2 实际上是 $2\r\r 表示转到行首。

    {print $2\r$1}会先打印$2,然后返回头部,再打印$1。所以字段 2 被字段 1 覆盖。

    【讨论】:

    • 欢迎来到 Stack Overflow,SleepyProgrammer!如果可以的话,我建议您添加更多详细信息。此帖子看起来像评论,可能会被删除...
    【解决方案2】:

    几个一般提示(除了 DOS 行结束问题)

    cat 用于连接文件,它不是唯一可以读取文件的工具!如果命令不读取文件,则使用command < file 之类的重定向。

    您可以使用-F 选项设置字段分隔符,而不是:

    cat foo | awk 'BEGIN{FS="|"} {print $2 " " $1}' 
    

    试试:

    awk -F'|' '{print $2" "$1}' foo 
    

    这将输出:

    com.emailclient.account name1@gmail.com
    com.socialsite.auth.accoun name2@msn.com
    

    要获得所需的输出,您可以做很多事情。我可能会split()第二个字段:

    awk -F'|' '{split($2,a,".");print a[2]" "$1}' file
    emailclient name1@gmail.com
    socialsite name2@msn.com
    

    最后将第一个字符转换为大写在awk 中有点痛苦,因为你没有一个很好的内置ucfirst() 函数:

    awk -F'|' '{split($2,a,".");print toupper(substr(a[2],1,1)) substr(a[2],2),$1}' file
    Emailclient name1@gmail.com
    Socialsite name2@msn.com
    

    如果你想要更简洁的东西(尽管你放弃了一个子流程)你可以这样做:

    awk -F'|' '{split($2,a,".");print a[2]" "$1}' file | sed 's/^./\U&/'
    Emailclient name1@gmail.com
    Socialsite name2@msn.com
    

    【讨论】:

    • 谢谢,这也非常很有帮助!
    【解决方案3】:

    使用点或竖线作为字段分隔符:

    awk -v FS='[.|]' '{
        printf "%s%s %s.%s\n", toupper(substr($4,1,1)), substr($4,2), $1, $2
    }' << END
    name1@gmail.com|com.emailclient.account
    name2@msn.com|com.socialsite.auth.account
    END
    

    给予:

    Emailclient name1@gmail.com
    Socialsite name2@msn.com
    

    【讨论】:

    • 这是我最初的想法,但.co.uk.cam.ac.uk 等等……变得一团糟。
    【解决方案4】:

    awk 没问题。我猜该文件来自 Windows 系统,并且在行尾有一个 CR (^m ascii 0x0d)。

    这将导致光标移动到 $2 之后的行首。

    使用带有:se ff=unix 的dos2unix 或vi 来消除CR。

    【讨论】:

    • 每一行都以 0x0d0a 结尾,你是这个意思吗?削减这些十六进制值会解决问题吗?谢谢
    • 0a 没问题,去掉 0d 就好了
    • 谢谢!将以下内容添加到管道中可以解决问题: | sed 's/\x0d//g' |
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2014-05-13
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    相关资源
    最近更新 更多