这是输入(样本):
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来弄乱输出。
有任何提示/建议吗?谢谢。
答案 0 :(得分:59)
一些常规提示(除了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
答案 1 :(得分: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
答案 2 :(得分:1)
awk还可以。我猜这个文件来自windows系统,并且在行尾有一个CR(^ m ascii 0x0d)。
这将导致光标在$ 2之后转到行的开头。
将dos2unix或vi与:se ff=unix
一起使用以消除CR。
答案 3 :(得分:0)
也许您的文件包含CRLF终止符。每一行后跟\ r \ n。
awk
会识别$2
实际$2\r
。 \r
表示转到该行的开头。
{print $2\r$1}
将首先打印$2
,然后返回头部,然后打印$1
。因此,字段2被字段1覆盖。