Com GNU ou FreeBSD sed
:
$ sed -E 's/^(([^"#]|"(\.|[^\"])*")*)#.*//' << EOF
heredoc> hi this is "#test" #this is comment
heredoc> this is test # comment with # characters
heredoc> hi this is "\"test" #this is comment as " was escaped earlier
heredoc> EOF
hi this is "#test"
this is test
hi this is "\"test"
A ideia é combinar #.*
que segue uma sequência de:
- caracteres diferentes de
"
ou#
([^"#"]
) - ou
"..."
entre aspas onde...
é uma sequência de:-
\x
: barra invertida seguida por qualquer caractere (\.
) - ou um caractere diferente de
"
ou\
.
-
POSIXly (onde não há nenhum operador alternação ( |
) ( ainda )), você poderia escrever:
sed 's/^\(\(\("\(\(\.\)\{0,1\}[^\"]\)*"\)\{0,1\}[^"#]\)*\)#.*//'
Lá, em vez de ERE (a|b)*
, usamos BRE \(a\{0,1\}b\)*
, ou seja, em vez de uma sequência de a
ou b
, usamos uma sequência de b
opcionalmente precedida por a
.