在循环中替换每一个大行中的第 n 个出现

Posted

技术标签:

【中文标题】在循环中替换每一个大行中的第 n 个出现【英文标题】:Replace every n'th occurrence in huge line in a loop 【发布时间】:2015-08-07 22:34:01 【问题描述】:

我有这行例如:

1,2,3,4,5,6,7,8,9,10

我想在每第二次出现 "," 时插入一个换行符 (\n)(用换行符替换第二次)。

【问题讨论】:

你试过什么?使用 for 循环并使用布尔值,应该不难 是的,还有:预期的输出是什么? 当人们发布 cmets 要求澄清时,您应该 edit 您的问题以添加更多详细信息。 当人们完全回答你的问题时,你应该反过来回答;) 【参考方案1】:

如果我理解您正在尝试正确执行的操作,那么

echo '1,2,3,4,5,6,7,8,9,10' | sed 's/\([^,]*,[^,]*\),/\1\n/g'

似乎是最直接的方法。 \([^,]*,[^,]*\) 将捕获1,23,4 等,它们之间的逗号通过通常的s///g 替换为换行符。这将打印

1,2
3,4
5,6
7,8
9,10

【讨论】:

【参考方案2】:

无法向 Wintermutes 答案添加评论,但它不需要第一个 , 部分,因为它必须有前一个字段以逗号分隔。

sed 's/\(,[^,]*\),/\1\n/g'

效果一样

另外我会添加另一个替代方案(虽然更糟并且会留下一个尾随换行符)

echo "1,2,3,4,5,6,7,8,9,10" | xargs -d"," -n2 | tr ' ' ','

【讨论】:

回复“它必须有一个以前的字段以逗号分隔”。我不同意您的这种说法,@wintermute 的回答只是添加了一个更易读的意图,即使在第一个昏迷之前没有任何内容,它也会起作用,因为它匹配 0 或无限次非昏迷字符。任何字段都可以为空,在这种情况下,正则表达式将在第二个逗号处停止匹配并打印一个逗号后跟一个换行符。 @Tensibai Nothing 仍然是一个字段。 我没有得到你的评论,我只是说其他答案和你的一样,但更容易理解。【参考方案3】:

我会使用 awk 来做到这一点:

$ awk -F, ' for (i=1; i<=NF; ++i) printf "%s%s", $i, (i%2?FS:RS) ' file
1,2
3,4
5,6
7,8
9,10

它遍历每个字段,根据i%2 的值打印每个字段后跟字段分隔符(定义为逗号)或记录分隔符(换行符)。

它比其他人提供的 sed 版本略长,但它的一个好处是您可以通过将2 更改为您喜欢的任何值来轻松更改每行的列数。

在字段数不能整除的情况下,为避免在最后一个字段后面出现逗号,您可以将三元组更改为i&lt;NF&amp;&amp;i%2?FS:RS

【讨论】:

【参考方案4】:

这可能对你有用(GNU sed):

sed 's/,/\n/2;P;D' file

【讨论】:

如果您能添加解释为什么它有效,那就太好了。谢谢 @Taavi s/,/\n/2 命令将第二个 , 替换为换行符。 P 命令打印到并包括模式空间中的第一个换行符。 D 命令删除最多并包括第一个换行符,然后,如果模式空间不为空,则从第一个开始重复所有 sed 命令,但不会像d 命令那样用下一行替换模式空间。因此,模式空间被转换为多行,直到下一行被引入时完全消耗。

以上是关于在循环中替换每一个大行中的第 n 个出现的主要内容,如果未能解决你的问题,请参考以下文章

python如何替换array(x,n)中每个x的第一个f(x)值

每个字符串每出现第 2 次,分别用文件的第 n 行替换两个不同的字符串

如何替换sql server中的第n个字符

12指定长度替换制表符

如何用另一个文件中的映射值替换 csv 文件中的第 n 个字段?

替换文件中的第 N 个字符串匹配项