web-dev-qa-db-ja.com

最初にフィールド$ 2を印刷し、次にフィールド$ 1を印刷するAWK

入力(サンプル)は次のとおりです。

[email protected]|com.emailclient.account
[email protected]|com.socialsite.auth.account

私はこれを達成しようとしています:

Emailclient [email protected]
Socialsite [email protected]

このようにAWKを使用する場合:

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

フィールド2の上にフィールド1を重ねることで出力を台無しにします。

ヒント/提案はありますか?ありがとうございました。

30
Sazzy

いくつかの一般的なヒント(DOS行末の問題を除く)

catはファイルを連結するためのもので、ファイルを読み取ることができる唯一のツールではありません!コマンドがファイルを読み取らない場合は、command < fileなどのリダイレクトを使用します。

次の代わりに-Fオプションを使用してフィールド区切り文字を設定できます。

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

試してください:

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

これは出力されます:

com.emailclient.account [email protected]
com.socialsite.auth.accoun [email protected]

目的の出力を得るには、さまざまなことを行うことができます。おそらくsplit() 2番目のフィールド:

awk -F'|' '{split($2,a,".");print a[2]" "$1}' file
emailclient [email protected]
socialsite [email protected]

最後に、最初の文字を大文字に変換することは、ucfirst()関数にNiceが組み込まれていないため、awkを少し苦しめます。

awk -F'|' '{split($2,a,".");print toupper(substr(a[2],1,1)) substr(a[2],2),$1}' file
Emailclient [email protected]
Socialsite [email protected]

もっと簡潔なものが必要な場合(サブプロセスをあきらめますが)できます:

awk -F'|' '{split($2,a,".");print a[2]" "$1}' file | sed 's/^./\U&/'
Emailclient [email protected]
Socialsite [email protected]
63
Chris Seymour

フィールド区切り記号としてドットまたはパイプを使用します。

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

与える:

Emailclient [email protected]
Socialsite [email protected]
3
glenn jackman

Awkは大丈夫です。ファイルはWindowsシステムのもので、行末にCR(^ m ascii 0x0d)があると推測しています。

これにより、カーソルは$ 2の後の行の先頭に移動します。

Dos2unixまたはviを:se ff=unixとともに使用して、CRを取り除きます。

2
parkydr

ファイルにCRLFターミネーターが含まれている可能性があります。すべての行の後に\ r\nが続きます。

awk$2を実際に認識します$2\r\rは、行の先頭に移動することを意味します。

{print $2\r$1}は最初に$2を出力し、次に先頭に戻り、次に$1を出力します。したがって、フィールド2はフィールド1によってオーバーレイされます。

1