使用awk

使用awk

単一行を3列の複数行に分割する方法があります。ファイルのすべての行の末尾に改行文字がありません。

私はawkを使ってみましたが、行ごとに3つの列の代わりに各列を行に分割します。

awk '{ gsub(",", "\n") } 6' filename

内容filenameは次のとおりです。

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O

目的の出力には1行あたり3つの列があります。

A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

答え1

使用awk

$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

どのように動作しますか?

  • -v RS='[,\n]'

    これは、awkにカンマまたは改行文字をレコード区切り文字として使用するように指示します。

  • a=$0; getline b; getline c

    これはawkに現在の行を変数に保存し、次の行をa変数に保存し、b次の行を変数に保存するように指示しますc

  • print a,b,c

    これはawkにabとを印刷するように指示します。c

  • OFS=,

    これは、awkに出力でフィールド区切り文字としてコンマを使用するように指示します。

使用trpaste

$ tr , '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

どのように動作しますか?

  • tr , '\n' <filename

    カンマを改行文字に変換中にファイル名から読み込みます。

  • paste -d, - - -

    次に、標準入力からpaste3行(それぞれ1行)を読み、一緒に貼り付けます。各行はカンマ()で区切られています。--d,

awkの代替

$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

どのように動作しますか?

  • -v RS='[,\n]'

    これは、awkにカンマまたは改行文字をレコード区切り文字として使用するように指示します。

  • printf "%s%s",$0,(NR%3?",":"\n")

    NRこれはawkに現在の行を印刷し、現在の行番号の値(モジュロ3)に従ってコンマまたは改行文字が続くように指示します。

答え2

sed 's/\(\([^,]\+,\)\{3\}\)/\1\n/g;s/,\n/\n/g' filename

あなたが解決策を求めたことを知っていますawk。今回はこの回答の編集内容として送信しようとしています。しかし、私にとってはsed解決策はより簡単でした...ユーザーjohn1024が素晴らしい解決策で私に勝ちましたawk。見てください。彼のpaste解決策はtrおそらく最も適切な古典的なUNIXの答えです。

  1. このソリューションは、GNU sedの拡張正規表現機能を使用します。

  2. \(..\)正規表現コレクションのグループです。このソリューションは2つを使用しますが、1つは他の1つに入れ子になっています。

  3. [^,]+,カンマの後にカンマが続く文字列です。あなたの場合は列またはフィールドです。

  4. \{3\}前の正規表現を 3 回使用する正規表現の乗数です。

  5. \1正規表現の逆参照です。前の正規表現として。

  6. g行のすべてのインスタンスに対してこれを行うことを意味します。

  7. s/,\n/\n/g末尾のカンマを削除してください。sed入力はまだ行で処理されるため、ここに改行文字を含める必要があります。

関連情報