AWK首先打印$ 2,然后打印$ 1

这里是input(样本):

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来混淆输出。

任何提示/build议? 谢谢。

几个一般的技巧(除了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 

使用点或管道作为字段分隔符:

 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 

awk是好的。 我猜这个文件是从一个Windows系统,并在行的末尾有一个CR(^ m ascii 0x0d)。

这将导致光标到$ 2后面的行的开始。

使用dos2unix或vi :se ff=unix来摆脱CR。

也许你的文件包含CRLF终止符。

每行都有\ r \ n。 awk认识到$ 2实际上是$ 2 \ r 。 \ r的意思是开始行。

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