Uso:
sed '/^<?xml/d' filename
Sob o GNU sed, \? significa zero ou um dos caracteres anteriores. (No POSIX sed, \? é indefinido.) Como você deseja corresponder a um literal ? , deixe-o sem escape.
Exemplos
Vamos considerar este arquivo de teste:
$ cat filename
<?xml deleteme
<.xml keepme
..xml keepme
A solução acima produz o resultado desejado:
$ sed '/^<?xml/d' filename
<.xml keepme
..xml keepme
O primeiro comando na pergunta incorretamente não produz resultados:
$ sed '/<\?xml/d' filename
$
Isso ocorre porque corresponde a todas as linhas que contêm xml , opcionalmente precedidas por < . Como todas as linhas contêm xml , todas elas são excluídas.
O segundo comando não exclui nada:
$ sed '/^<\?xml/d' filename
<?xml deleteme
<.xml keepme
..xml keepme
Isso exclui qualquer linha que comece com zero ou um < seguido imediatamente por xml . Como as linhas sempre têm pelo menos um caractere entre < e xml , nenhuma linha é excluída.
Como escapar de caracteres quando em dúvida
Se você não tiver certeza se um caractere é regex ativo e deseja desativá-lo, a melhor coisa a fazer é colocá-lo entre colchetes:
$ sed '/^[<][?]xml/d' filename
<.xml keepme
..xml keepme
Dentro de [...] , todos os caracteres são tratados como caracteres literais.