AWK 先打印字段 $2,然后打印字段 $1
Posted
技术标签:
【中文标题】AWK 先打印字段 $2,然后打印字段 $1【英文标题】:AWK to print field $2 first, then field $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 'BEGINFS="|" print $2 " " $1'
它通过在字段 2 的顶部覆盖字段 1 来混淆输出。
任何提示/建议?谢谢。
【问题讨论】:
【参考方案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 'BEGINFS="|" 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' |以上是关于AWK 先打印字段 $2,然后打印字段 $1的主要内容,如果未能解决你的问题,请参考以下文章