単一行を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に
a
、b
とを印刷するように指示します。c
OFS=,
これは、awkに出力でフィールド区切り文字としてコンマを使用するように指示します。
使用tr
とpaste
$ 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, - - -
次に、標準入力から
paste
3行(それぞれ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の答えです。
このソリューションは、GNU sedの拡張正規表現機能を使用します。
\(..\)
正規表現コレクションのグループです。このソリューションは2つを使用しますが、1つは他の1つに入れ子になっています。[^,]+,
カンマの後にカンマが続く文字列です。あなたの場合は列またはフィールドです。\{3\}
前の正規表現を 3 回使用する正規表現の乗数です。\1
正規表現の逆参照です。前の正規表現として。g
行のすべてのインスタンスに対してこれを行うことを意味します。s/,\n/\n/g
末尾のカンマを削除してください。sed
入力はまだ行で処理されるため、ここに改行文字を含める必要があります。