首先打印字段$2,然后字段$1。

时间:2022-01-18 22:07:42

Here is the input(sample):

这里是输入(示例):

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

I'm trying to achieve this:

我正在努力做到这一点:

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

If I use AWK like this:

如果我像这样使用AWK:

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

it messes up the output by overlaying field 1 on the top of field 2.

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

Any tips/suggestions? Thank you.

任何建议/建议吗?谢谢你!

4 个解决方案

#1


49  

A couple of general tips (besides the DOS line ending issue):

一些一般的建议(除了DOS的结束问题):

cat is for concatenating files, it's not the only tool that can read files! If a command doesn't read files then use redirection like command < file.

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

You can set the field separator with the -F option so instead of:

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

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

Try:

试一试:

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

This will output:

这将输出:

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

To get the desired output you could do a variety of things. I'd probably split() the second field:

为了得到所需的输出,您可以做很多事情。我可能会把第二个字段分开:

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

Finally to get the first character converted to uppercase is a bit of a pain in awk as you don't have a nice built in ucfirst() function:

最后,要将第一个字符转换为大写,在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

If you want something more concise (although you give up a sub-process) you could do:

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

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

#2


3  

Use a dot or a pipe as the field separator:

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

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

gives:

给:

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

#3


1  

The awk is ok. I'm guessing the file is from a windows system and has a CR (^m ascii 0x0d) on the end of the line.

awk是好的。我猜这个文件从windows系统和CR(^米ascii 0 x0d)线的结束。

This will cause the cursor to go to the start of the line after $2.

这将导致游标在$2之后转到行首。

Use dos2unix or vi with :se ff=unix to get rid of the CRs.

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

#4


0  

Maybe your file contains CRLF terminator.

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

Every lines followed by \r\n. awk recognizes the $2 actually $2\r. The \r means goto the start of the line.

每一行后面都是\r\n。awk承认2美元实际上是2美元。\r意味着要开始排队。

{print $2\r$1} will print $2 first, then return to the head, then print $1. So the field 2 is overlaid by the field 1.

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

#1


49  

A couple of general tips (besides the DOS line ending issue):

一些一般的建议(除了DOS的结束问题):

cat is for concatenating files, it's not the only tool that can read files! If a command doesn't read files then use redirection like command < file.

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

You can set the field separator with the -F option so instead of:

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

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

Try:

试一试:

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

This will output:

这将输出:

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

To get the desired output you could do a variety of things. I'd probably split() the second field:

为了得到所需的输出,您可以做很多事情。我可能会把第二个字段分开:

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

Finally to get the first character converted to uppercase is a bit of a pain in awk as you don't have a nice built in ucfirst() function:

最后,要将第一个字符转换为大写,在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

If you want something more concise (although you give up a sub-process) you could do:

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

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

#2


3  

Use a dot or a pipe as the field separator:

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

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

gives:

给:

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

#3


1  

The awk is ok. I'm guessing the file is from a windows system and has a CR (^m ascii 0x0d) on the end of the line.

awk是好的。我猜这个文件从windows系统和CR(^米ascii 0 x0d)线的结束。

This will cause the cursor to go to the start of the line after $2.

这将导致游标在$2之后转到行首。

Use dos2unix or vi with :se ff=unix to get rid of the CRs.

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

#4


0  

Maybe your file contains CRLF terminator.

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

Every lines followed by \r\n. awk recognizes the $2 actually $2\r. The \r means goto the start of the line.

每一行后面都是\r\n。awk承认2美元实际上是2美元。\r意味着要开始排队。

{print $2\r$1} will print $2 first, then return to the head, then print $1. So the field 2 is overlaid by the field 1.

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