私のUnix出力は
ABC : 123
DEFG : 4587
MJk : 36
次の同じ区切り文字を使用して、すべての行を単一の行にマージしたいと思います。
ABC DEFG MJK : 123 4587 36
私は単一の列に出力を印刷するためにawkを使用することを知っています。
awk'{print $1}' | tr '\n' ' '
しかし印刷中
ABC DEFG MJK
値ではない 123 4587 36
答え1
$ awk -F: '{a=a $1; b=b $2} END{print a FS b}' file
ABC DEFG MJk : 123 4587 36
tr '\n' ' '
最近、人々は改行文字を別のものに変換するために同様の方法を使用する多くの投稿を見ました。 POSIXテキストファイル(すべてのPOSIXテキスト処理ツールで読み取ることができます)を他のYMMV形式のファイルに変換するので、まれな場合を除いてこれを行わないでください。 POSIX テキスト行は で終わり\n
、 POSIX txt ファイルは POSIX テキスト行で構成されます。tr
あるいは、他の方法を使用してすべての改行を削除すると、後続のPOSIXテキスト処理ツール(awk、sedなど)はそれを入力として使用して未定義の動作を実行できます。
以下は予期しませんでしたが、実際にPOSIXで定義されている他の動作のいくつかの例です。この複数行の文字列をスペースで区切られた単一行に変換するとします。
$ printf 'foo\nbar\n' | wc -l
2
tr
すべてを削除するには\n
:
$ printf 'foo\nbar\n' | tr '\n' ' '
foo bar $
$ printf 'foo\nbar\n' | tr '\n' ' ' | wc -l
0
POSIXテキストファイルと同じように出力するより良いアプローチと比較して、次にパイプするときのより直感的な結果を提供しますwc
。
$ printf 'foo\nbar\n' | paste -sd ' ' -
foo bar
$ printf 'foo\nbar\n' | paste -sd ' ' - | wc -l
1
答え2
これはsedエディタを使用して、tgeパターン領域に次の行を追加し、中央コロンの周りのフィールドを混在させることで実行できます。テストコマンドはeofまで繰り返され、各反復で次の行を選択します。
sed -Ee '
:a;$!N;s/(.*):(.*)\n(.*):(.*)/\1\3:\2\4/;ta
' file
awkのバージョンは説明を必要としません。
awk -F ':' -v ORS='' '
{ a[NR] = $1; b[NR] = $2 }
END {
a[NR] = a[NR] FS
for (i=1; i<=2*NR; i++)
print i<=NR ? a[i] : b[i-NR]
print RS
}
' file
結果:
ABC DEFG MJK : 123 4587 36
答え3
内容全体をバッファリングする必要があるようです。次のことを試すことができます。
awk '{FNR==1{first=$1; second=$3} FNR>1{first=first " " $1; second=second " " $3} END{printf("%s : %s\n", first, second)}'
これは、変数のすべての行に対するすべての「最初の列項目」の内容first
と変数の「2番目の列項目」の内容を累積します(実際には3番目の列です。sの観点からは、:
独自の列を形成するためです) )。行)。awk
変えるsecond
。最後に、:
区切り文字を区切り文字として使用して、累積バッファを印刷します。
先行/末尾のスペースが問題にならない場合は、コードを次のように短縮できます。
awk '{first=first " " $1; second=second " " $3} END{printf("%s : %s\n", first, second)}'
答え4
むしろ、各列を配列に保存してから、希望の形式で印刷したいと思います。
awk -F" : " '{a[NR]=$1;b[NR]=$2} END{ for(i=1;i<=NR;i++) printf "%s ",a[i]; printf ": "; for(i=1;i<=NR;i++) printf "%s ",b[i];}' file
-F" : "
" : "
区切り文字に基づいて列を区切ります。{a[NR]=$1;b[NR]=$2}
2 つの配列インデックス =NR
(行数) と値 = 対応する行の列値を作成します。printf
希望の順序で印刷します。 (printf
aは印刷されませんnewline
。)