【问题标题】:Replacing a specific whitespace pattern in sed with a newline, when it doesn't have a preceding colon?当 sed 中没有前面的冒号时,用换行符替换特定的空格模式?
【发布时间】:2018-11-16 16:32:49
【问题描述】:

我正在尝试使用 sed 解析以下行,以便仅当空格不在冒号之前时用换行符替换空格。

例如,我正在使用以下输入进行处理:

label1: output label2: output2 label3: "output3" label4: output4 { label5: output5 label6: output6 } label7: output7 { { { label8: output8 } label9: output9 } } label10: output10

我希望正则表达式用换行符替换前面没有冒号的任何空格,因此输出将是这样的:

label1: output
label2: output2
label3: "output3"
label4: output4
{
label5: output5
label6: output6
}
label7: output7
{
{
{
label8: output8
label9: output9
}
}
label10: output10

当我尝试在cat file | sed 's/[^:A-Za-z0-9\"] /%/g' | tr '%' '\n' 中使用以下正则表达式时,它会产生以下输出,这很接近但没有达到目标:

    label1: output label2: output2 label3: "output3" label4: output4
    label5: output5 label6: output6
    label7: output7


    label8: output8
    label9: output9

    label10: output10

我也试过这个cat file | sed 's/[^:A-Za-z0-9\"] /%/g' | tr '%' '\n',结果是

label1: outpu
label2: output
label3: "output3
label4: output

label5: output
label6: output

label7: output



label8: output

label9: output


label10: output10

看起来像正则表达式还包括用换行符替换不是: 的所有其他字符。

【问题讨论】:

  • 你想避免useless use of cat
  • “不是冒号(或换行)”的正则表达式是[^:];从您的问题中不清楚您是否还希望替换后跟空格的换行符。

标签: regex sed


【解决方案1】:

应该这样做:

sed -E 's/([^:]) /\1\n/g' file

输出:

label1: output
label2: output2
label3: "output3"
label4: output4
{
label5: output5
label6: output6
}
label7: output7
{
{
{
label8: output8
}
label9: output9
}
}
label10: output10

干杯!

【讨论】:

  • 欢迎来到 StackOverflow!您的答案需要更多关于代码如何工作的解释才能成为一个好的答案。
  • -r 选项不可移植;并非所有 sed 变体都支持转义 \n 换行符。
  • 将 -r 选项更改为 -E。不知道如何处理您对 \n 的评论
  • -E 也不可移植;这两个都超出了 POSIX 规范。有一种方法可以在 sed 脚​​本中嵌入文字换行符,但具体如何做到这一点也不是完全可移植的(通常,反斜杠换行符适用于大多数地方)。
【解决方案2】:

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

sed 'G;:a;s/\([^: ]\) \(.*\(.\)\)/\1\3\2/;ta;s/.$//' file

使用G 命令在当前行添加一个换行符,默认情况下会在模式空间中添加一个空的保持空间。使用模式匹配和反向引用,遍历当前行,用附加的换行符替换非空格/非冒号字符后跟空格。当没有更多匹配项时,删除换行符并打印该行。

使用删除许多反斜杠的-r 选项(仅限GNU sed)可以更轻松地查看相同的解决方案:

sed  -r 'G;:a;s/([^: ]) (.*(.))/\1\3\2/;ta;s/.$//' file

正如所指出的,最佳解决方案是:

sed  's/\([^: ]\) /\1\n/g' file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多