sed:匹配“除换行符之外的任何字符”的便携式解决方案

Phi*_*pos 5 sed posix regular-expression

我可以通过以下方式匹配换行符\n

echo "one
two" | sed 'N;s/\n/_/g'
Run Code Online (Sandbox Code Playgroud)

在 GNU 中sed,我可以用来[^\n]匹配除换行符之外的任何字符:

echo "one
two" | sed 'N;s/[^\n]/_/g'
Run Code Online (Sandbox Code Playgroud)

这非常方便,但它违反了 POSIX。其他sed版本正确回答__n______

与制表符相同,但我可以通过使用实际的制表符(前面是 ctrl-v)来解决。但这不适用于换行符:

echo "one
two" | sed 'N;s/[^
]/_/g'
Run Code Online (Sandbox Code Playgroud)

给我unbalanced brackets

[^[:cntrl:]]仅当没有我想要匹配的其他控制字符时才使用有效。

那么在 POSIX 中匹配除换行符之外的任何字符的正确方法是什么sed

小智 1

实际上,有一种非常巧妙的方法可以以常规方式处理这种情况sed:将换行符与一些常规字符(例如 _)交换,然后执行 [^_],然后返回。我本来想发布一个出现的问题的解决方案,但懒得发布它,但现在让我把它放在这里:

sed -e '
   /./!b

   :loop
      $q; N
   /\n$/bloop

   h

   /\ncreate table/!{
      s/\(.*\)\n.*/\1/p
      g;s/.*\(\n\)/\1/;D
   }

   g

   y/\n_/_\n/
      s/^[^_]*/test/
   y/\n_/_\n/

' input.data
Run Code Online (Sandbox Code Playgroud)

上述解决方案的问题陈述。