在每第 N 次出现分隔符后添加新行

Pra*_*rma 5 sed text-processing

我有一个roll.txt包含以下数据的文件,以逗号分隔格式,没有任何换行符。

'123456789','987651234','129873645','213456789','987612345','543216789','432156789','876543291','213465789','542637819','123456','23456','22234','3456','7890543','34567891,'2345','567'
Run Code Online (Sandbox Code Playgroud)

我需要在每 6出现逗号分隔符后插入一个新行,并且每行末尾没有逗号。

以下是预期的输出:

'123456789','987651234','129873645','213456789','987612345','543216789'
'432156789','876543291','213465789','542637819','123456','23456'
'22234','3456','7890543','34567891,'2345','567'
Run Code Online (Sandbox Code Playgroud)

我正在使用以下sed不起作用的命令。

sed 's/[^,]//g'
Run Code Online (Sandbox Code Playgroud)

ste*_*ver 5

至少对于 GNUsed假设您的字段不能包含嵌入的逗号分隔符,您可以这样做

sed 's/,/\n/6; P; D' roll.txt
Run Code Online (Sandbox Code Playgroud)

它反复尝试用换行符替换第 6 个逗号,打印,然后删除直到换行符的模式空间部分。

注意:没有必要实现显式标记的测试/分支,因为该D命令在该行的其余部分隐式“重新启动循环”:

D
如果模式空间不包含换行符,则启动正常的新循环,就像发出 d 命令一样。否则,删除模式空间中直到第一个换行符的文本,并使用生成的模式空间重新启动循环,而不读取新的 input 行

(感谢@RakeshSharma 澄清了这一点)。

前任。

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'
Run Code Online (Sandbox Code Playgroud)

或者,使用 Perl 的Text::CSV模块:

perl -MText::CSV -ne '
  BEGIN{$p = Text::CSV->new()} 
  @fields = $p->fields() if $p->parse($_); 
  do {
    print join ",", splice @fields, 0, 6; print "\n";
  } while @fields
' roll.txt
'123456789','987651234','129873645','213456789','987612345','543216789'
'432156789','876543291','213465789','542637819','123456','23456'
'22234','3456','7890543','34567891,'2345','567'
Run Code Online (Sandbox Code Playgroud)


αғs*_*нιη 5

随着trpaste

tr ',' '\n' <infile |paste -sd',,,,,\n'
Run Code Online (Sandbox Code Playgroud)

更多的可读性和可理解:

tr ',' '\n' <infile |paste --serial --delimiters=',,,,,\n'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当您想在每个N=100位置添加一个 NewLine 时,您可能不喜欢输入 99 个逗号',,,,,,,,,, ... ,\n';相反,让我们printf通过大括号扩展为您生成它。

tr ',' '\n' <infile |paste -sd $(printf '%.1s' ,{1..99})'\n'
Run Code Online (Sandbox Code Playgroud)

来自man paste

-d, --delimiters=LIST
       重用 LIST 中的字符而不是 TAB

-s, --serial
       一次粘贴一个文件而不是并行粘贴