Infelizmente, parece que não é possível usar o NUL como um separador para o comando s///
em sed.
Se você quiser criar uma string com um caractere NUL, você pode usar o formulário $'...'
que o bash e outros shells reconhecem, então você pode pensar que isso funcionaria:
sed -r -e $'s$ cat -v script.sed
s^@o^@x^@g
o$ echo "/path/to/a/folder" | sed -r -f script.sed
sed: file script.sed line 1: delimiter character is not a single-byte character
xcase 0: /* Special case of mbrtowc(3): the NUL character */
/* TODO: test this */
return 1;
g'
Mas a maneira como os argumentos são passados no Linux (e no Unix em geral) faz com que não seja realmente possível passar strings com NULs incorporadas, já que tudo que você obtém é um argc (number of arguments) e argv que é um array de char *
, em seguida, seqüências terminadas em NUL (C strings) é a única maneira possível de levar os argumentos. Em outras palavras, todo o sed (ou qualquer programa) verá se passou $'s
é simplesmente "s"
o^@
xs
g'unterminated 's' command
(e o NUL, que eles devem tomar como o final da string.)
Eu achei que talvez passar isso como um arquivo externo para o sed poderia funcionar, já que nesse caso o sed pode saber que os NULs estão embutidos e potencialmente rastrear a string completa pelo seu comprimento, então eu tentei isso:
/*
* Return zero in all other cases:
* CH is a valid single-byte character (e.g. 0x01-0x7F in UTF-8 locales);
* CH is an invalid byte in a multibyte sequence for the currentl locale,
* CH is the NUL byte.
*/
Os sed
s são os bytes NUL. Eu os inseri no vim usando Ctrl v 0 0 0 (tres zeros) qual é o pressionamento de tecla vim para inserir um caractere pelo seu valor ASCII.
Mas isso também não parece funcionar:
sed -r -e $'s$ cat -v script.sed
s^@o^@x^@g
o$ echo "/path/to/a/folder" | sed -r -f script.sed
sed: file script.sed line 1: delimiter character is not a single-byte character
xcase 0: /* Special case of mbrtowc(3): the NUL character */
/* TODO: test this */
return 1;
g'
Curiosamente, isso é diferente de quando há apenas um único is_mb_char()
no arquivo de script, caso em que o sed reclama de return 1
... Portanto, parece estar acompanhando a string pelo seu comprimento, mas ainda assim não parece feliz em usar o NUL como seu caractere separador.
Olhando o código-fonte de return 0
, não está claro se isso foi planejado ou se foi um bug. Na função mbrtowc(3)
, que tenta detectar se o byte é parte de um caractere de múltiplos bytes, manipular para NUL funciona assim :
/*
* Return zero in all other cases:
* CH is a valid single-byte character (e.g. 0x01-0x7F in UTF-8 locales);
* CH is an invalid byte in a multibyte sequence for the currentl locale,
* CH is the NUL byte.
*/
Nesse caso, L'%code%'
significa "sim, é um caractere de vários bytes", o que não é realmente o caso.
Um comentário que algumas linhas acima dizem :
%pre%Então, talvez %code% fosse pretendido?
A confirmação que introduziu este código não t tem muito mais contexto aqui ...A página do manual %code% menciona %code% , que eu suponho ser algum tipo de multi-byte NUL, então talvez seja por isso que eles decidiram lidar dessa maneira?
Espero que esta informação ainda seja útil!