【问题标题】:Replacing varying delimiters using sed or tr使用 sed 或 tr 替换不同的分隔符
【发布时间】:2013-05-25 11:36:52
【问题描述】:

我需要将 ID 列表从使用由 , 和/或 \r\n\n 组成的分隔符转换为使用 ,|。 (本质上是:s/[,\r\n]+/,\|/g 没有尾随 |

输入数据示例:

123,456,789,012

123,
456
789,
012

我需要得到的输出是123,|456,|798,|012,:每个字段以逗号结尾,并用管道分隔它们。

这看起来很简单,但我对如何管理它感到很困惑。我已经尝试过......实际上有很多方法,但似乎没有任何效果。以下是几个例子:

  1. sed "s/[,\r\n]+/,\|/g" < filename 不匹配任何分隔符。

  2. sed "s/(,|,?\r?\n?)/,\|/g" 也不匹配任何内容。

  3. tr -t "(,?(\r|\n)+)" ",\|"tr -t "[,\r\n]+" ",\|" 仅替换 ,

  4. tr "(,|\r?\n)" ",\|", 一起正常工作,但与,\n,\r\n 一起使用它会用多个条替换匹配的字符。例如:123|||456|||789|||012|

  5. 变得更复杂:sed ':a;N;$!ba;s/\n/,/g"(取自here)将\n 正确替换为,,但不适用于\r\n。将\n 替换为[,\r\n] 只会返回输入。

我被难住了。任何人都可以提供一些帮助或建议吗?

【问题讨论】:

  • 所以输出最后没有管道?在输出中,, 标记每个字段的结尾,| 分隔字段对?
  • 正确!我本来会在我的帖子中更清楚地说明这一点,但我在工作中被赶出了门。 :(
  • 谢谢!是的。我一直在等到今天可以在工作中测试它。

标签: sed newline tr


【解决方案1】:

我所做的是将 \r\n 序列标准化为 \n 以摆脱一个替代方案(并提高下一步的速度)。

perl -pi -e 'BEGIN { $/ = undef; } s/\r\n/\n/g; s/[,\n]/,|/g;'

更新:从您的示例中,您似乎打算用一次出现的 ,| 替换多次出现的分隔符,它们之间没有任何内容。如果这是您想要做的,那么将命令更改为:

perl -pi -e 'BEGIN { $/ = undef; } END { print ",\n"; } s/\r\n/\n/g; s/[,\n]+/,|/g;'

另外,你想要一个尾随 , 在最后一个字段之后。

【讨论】:

  • 很遗憾,目标环境无法访问perl。
【解决方案2】:

从您的示例输出来看,输出的末尾似乎没有管道; , 标记每个字段的结尾,| 分隔字段对。对于该规范,这适用于 trsed

$ x="123,
> 456
> 789,
> 012"
$ echo "$x" | tr -s '\r\n' ',' | sed 's/,\(.\)/,|\1/g'
123,|456,|789,|012,
$

tr 命令用逗号替换换行符和回车,压缩 (-s) 重复项。 sed 命令查找逗号后跟另一个字符并将其替换为,|

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-21
    • 2021-10-25
    • 1970-01-01
    • 2021-10-25
    • 2018-12-21
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多