6つのカンマごとに2つの区切り文字を追加します。

6つのカンマごとに2つの区切り文字を追加します。

頑張るこの質問を展開してくださいしかし、これを見つけることはできません。

ファイルがあるとしましょうroll.txt

echo "'123456789','987651234','129873645','213456789','987612345','543216789','432156789','876543291','213465789','542637819','123456','23456','22234','3456','7890543','34567891,'2345','567'" >> roll.txt

次のsedコマンドを使用すると、6つのカンマごとに改行文字を挿入できます。

sed 's/,/,\n/6; P; D' roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789',
'432156789','876543291','213465789','542637819','123456','23456',
'22234','3456','7890543','34567891,'2345','567'

しかし、カンマ6個ごとに改行2個を入れようとすると、次のようになります。

sed 's/,/,\n\n/6; P; D' roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789',

'432156789','876543291','213465789','542637819','123456','23456',



'22234','3456','7890543','34567891,'2345','567'

代わりに、6番目のカンマの後に2つの改行が表示されます。4つ12番目のカンマの後の改行文字です。なぜ? 6つのカンマごとに2つの改行を取得する方法は?

答え1

Steeldriverのコメントに記載されているように、各サイクルに2行を追加しますが、1行だけ印刷して削除します。長いシーケンス(3、7、15本の空白行を含む)では、状況はさらに悪化します。

したがって、最初の行が空の場合は交換しないでください。

sed '/^\n/!s/,/,\n\n/6; P; D'

答え2

マルチキャラクタRSにGNU awkを使用すると、各レコードを6つのカンマフィールドではなく6つのカンマフィールドとして定義できます。

$ echo "'123456789','987651234','129873645','213456789','987612345','543216789','432156789','876543291','213465789','542637819','123456','23456','22234','3456','7890543','34567891,'2345','567'" |
awk -v RS='([^,]*,){0,6}' 'RT{print RT}'
'123456789','987651234','129873645','213456789','987612345','543216789',
'432156789','876543291','213465789','542637819','123456','23456',
'22234','3456','7890543','34567891,'2345',

各出力行に6つのフィールドがあり、最後のフィールドが空の場合にのみ終了し、有効なCSVであることを確認するには、,次のようにします。

$ echo "'123456789','987651234','129873645','213456789','987612345','543216789','432156789','876543291','213465789','542637819','123456','23456','22234','3456','7890543','34567891,'2345','567'" |
awk -v n=6 'BEGIN{RS="([^,]*,){0,"n"}"; FS=OFS=","} RT{$0=gensub(/,$/,"",1,RT); $n=$n; print}'
'123456789','987651234','129873645','213456789','987612345','543216789'
'432156789','876543291','213465789','542637819','123456','23456'
'22234','3456','7890543','34567891,'2345',

答え3

使用幸せ(以前のPerl_6)

Rakuで要素を結合するには、batch次のように組み合わせることができます。

~$  raku -ne 'put join "\n", .split(",").batch(6).map: *.join(",");' roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789'
'432156789','876543291','213465789','542637819','123456','23456'
'22234','3456','7890543','34567891,'2345','567'

したがって、それぞれの間に2つの改行文字を取得するには、batch次のようにjoinします\n\n

~$  raku -ne 'put join "\n\n", .split(",").batch(6).map: *.join(",");' roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789'

'432156789','876543291','213465789','542637819','123456','23456'

'22234','3456','7890543','34567891,'2345','567'

Rakuの機能はbatchRakuの呼び出しと同じですrotor(..., :partial)。最後に不完全な6つの要素セットを削除するには、を呼び出すだけですrotor()

最後に、時にはsplittingが必要な答えを常に提供していないことがあります。この場合、combデータを参照して興味のある要素を抽出できます。以下のコードは上記の答えとまったく同じコードを提供しますが、概念的にはより簡単です。唯一の難しさは、'アポストロフィが1行の引用を混乱させる可能性があるため、文字をUnicode名で宣言できることです\c[APOSTROPHE]

~$ raku -ne 'put join "\n\n", .comb(/ \c[APOSTROPHE] \d+ \c[APOSTROPHE] /).batch(6).map: *.join(",");'  roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789'

'432156789','876543291','213465789','542637819','123456','23456'

'22234','3456','7890543','2345','567'

https://unix.stackexchange.com/a/611077/227738
https://docs.raku.org/言語/regexes
https://raku.org

答え4

使用awk:

$ awk -F, '{for (i=1;i<NF;i++) printf "%s", $i FS ((i%6==0) ? ORS ORS: "") }END{print $NF; print ""}' file
'123456789','987651234','129873645','213456789','987612345','543216789',

'432156789','876543291','213465789','542637819','123456','23456',

'22234','3456','7890543','34567891,'2345','567'

関連情報