Eu tenho um arquivo de texto sendo processado em uma máquina Windows. É necessário remover os caracteres de tabulação antes de usar bcp
o utilitário para carregar os dados do arquivo em uma tabela de banco de dados.
O seguinte comando, em um script Bash, retirou as guias à direita:
sed 's/[\t]*$//' < ./input/raw.txt >> ./input/data.txt
mas converteu o CR
- LF
para LF
o qual causou bcp
a falha do comando.
Em um esforço para manter o CR
- LF
eu tentei isso:
sed 's/[\t]*$/$CR/' < ./input/raw.txt >> ./input/data.txt
mas isso resultou em:
O resultado desejado é:
Como faço para modificar o comando para obter a saída desejada?
Você precisa instalar o
unix2dos
pacote. Possui dois utilitários:Vamos criar um arquivo de teste de cinco linhas e fazer um dump hexadecimal para examinar os finais de linha:
Vemos que cada linha termina em um caractere de nova linha, hex 0a.
Agora, convertemos essas novas linhas em finais de linha DOS CR-LF e inspecionamos novamente:
Agora cada linha termina em CR-LF, hex 0d 0a.
Por fim, podemos converter o arquivo de volta para as novas linhas originais do UNIX:
Observe que em standard
sed
,sed 's/[\t]*$//'
remove todas as barras invertidas et
caracteres do final da linha. A implementação GNU desed
só faz isso quando há umaPOSIXLY_CORRECT
variável em seu ambiente.sed 's/\t*$//'
não é especificado, mas pelo menos com GNUsed
, isso acontece para remover TABs à direita,POSIXLY_CORRECT
esteja no ambiente ou não.Aqui você poderia fazer:
$'...'
Usando a forma de aspas no estilo ksh93 dentro das quais coisas como\t
ou\r
são expandidas para TAB e CR, respectivamente. Isso agora é suportado por muitos outros shells e estará na próxima versão do padrão POSIX parash
.Se você tiver caracteres TAB e CR em variáveis de shell, o que você poderia fazer sem,
$'...'
por exemplo, com:Você poderia fazer:
Mas isso tem que estar entre aspas duplas. Dentro de aspas simples, nenhuma expansão é executada.
Agora, no caso improvável de a entrada não terminar em um caractere LF (o que tornaria um texto inválido no Unix), aqueles (pelo menos com GNU) produziriam um arquivo que termina
sed
em um caractere CR, tornando-o inválido em DOS também.Para converter os arquivos de texto de Unix para DOS, você pode usar o
unix2dos
utilitário que não teria o problema:Ou use o modo
perl
'ssed
:perl -p
funciona assimsed
no sentido de rodar o código para cada linha de entrada, exceto que noperl
espaço padrão ($_
aí) tem a linha completa incluindo o delimitador de linha. Ele também oferece suporte a escapes\t
,\n
,\r
(enquanto o padrãosed
oferece suporte apenas\n
e apenas em expressões regulares) e pode lidar com arquivos que não sejam de texto.Usando Raku (anteriormente conhecido como Perl_6)
Raku (aka Perl6) é uma linguagem de programação da família Perl. Uma coisa que o projeto Perl6 tentou fazer foi abstrair as imperfeições específicas do sistema operacional para tornar o código mais portátil, e uma dessas imperfeições é o processamento de novas linhas. O Raku fornece um
nl-in
parâmetro para entrada do identificador de arquivo (o padrão é["\x0A", "\r\n"]
), autochomps linhas por padrão, usa\n
novas linhas terminadas internamente e fornece umnl-out
parâmetro para saída do identificador de arquivo (padrão é"\n"
).A declaração principal do OP é a seguinte:
Portanto, para o script Raku acima (em qualquer plataforma em que você esteja trabalhando), você pode abrir um arquivo para gravação e definir
nl-out => \r\n
, ou seja, nova linha para CRLF. Raku lêlines
preguiçosamente, portanto, esse script deve ser eficiente em termos de memória. Mesmo sem tornar o script acima executável, você pode chamá-lo na linha de comando da seguinte maneira:O padrão do script acima é usar
$*IN
stdin e, portanto, é "único", mas o Raku também fornece funções para leitura$*ARGFILES
e diretórios.dir
Por fim, há um excelente resumo do processamento de nova linha no Raku no primeiro link abaixo:https://docs.raku.org/language/newline.html
https://raku.org