AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 742727
Accepted
knot22
knot22
Asked: 2023-04-13 04:13:46 +0800 CST2023-04-13 04:13:46 +0800 CST 2023-04-13 04:13:46 +0800 CST

Adicione um CR antes de cada LF

  • 772

Eu tenho um arquivo de texto sendo processado em uma máquina Windows. É necessário remover os caracteres de tabulação antes de usar bcpo 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- LFpara LFo qual causou bcpa falha do comando.

Em um esforço para manter o CR- LFeu tentei isso:

sed 's/[\t]*$/$CR/' < ./input/raw.txt >> ./input/data.txt

mas isso resultou em:

insira a descrição da imagem aqui

O resultado desejado é:

insira a descrição da imagem aqui

Como faço para modificar o comando para obter a saída desejada?

bash
  • 3 3 respostas
  • 1720 Views

3 respostas

  • Voted
  1. Jim L.
    2023-04-13T04:22:40+08:002023-04-13T04:22:40+08:00

    Você precisa instalar o unix2dospacote. Possui dois utilitários:

    unix2dos    Convert UNIX newlines to CR-LF
    dos2unix    Convert DOS CR-LF to UNIX newlines
    

    Vamos criar um arquivo de teste de cinco linhas e fazer um dump hexadecimal para examinar os finais de linha:

    $ jot -w 'line %d' 5 > foo
    $ hexdump -C foo
    00000000  6c 69 6e 65 20 31 0a 6c  69 6e 65 20 32 0a 6c 69  |line 1.line 2.li|
    00000010  6e 65 20 33 0a 6c 69 6e  65 20 34 0a 6c 69 6e 65  |ne 3.line 4.line|
    00000020  20 35 0a                                          | 5.|
    00000023
    

    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:

    $ unix2dos foo
    $ hexdump -C foo
    00000000  6c 69 6e 65 20 31 0d 0a  6c 69 6e 65 20 32 0d 0a  |line 1..line 2..|
    00000010  6c 69 6e 65 20 33 0d 0a  6c 69 6e 65 20 34 0d 0a  |line 3..line 4..|
    00000020  6c 69 6e 65 20 35 0d 0a                           |line 5..|
    00000028
    

    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:

    $ dos2unix foo
    $ hexdump -C foo
    00000000  6c 69 6e 65 20 31 0a 6c  69 6e 65 20 32 0a 6c 69  |line 1.line 2.li|
    00000010  6e 65 20 33 0a 6c 69 6e  65 20 34 0a 6c 69 6e 65  |ne 3.line 4.line|
    00000020  20 35 0a                                          | 5.|
    00000023
    
    • 23
  2. Best Answer
    Stéphane Chazelas
    2023-04-13T04:22:16+08:002023-04-13T04:22:16+08:00

    Observe que em standard sed, sed 's/[\t]*$//'remove todas as barras invertidas e tcaracteres do final da linha. A implementação GNU de sedsó faz isso quando há uma POSIXLY_CORRECTvariável em seu ambiente.

    sed 's/\t*$//'não é especificado, mas pelo menos com GNU sed, isso acontece para remover TABs à direita, POSIXLY_CORRECTesteja no ambiente ou não.

    Aqui você poderia fazer:

    sed $'s/\t*$/\r/'
    

    $'...'Usando a forma de aspas no estilo ksh93 dentro das quais coisas como \tou \rsã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 para sh.

    Se você tiver caracteres TAB e CR em variáveis ​​de shell, o que você poderia fazer sem, $'...'por exemplo, com:

    eval "$(printf 'TAB="\t" CR="\r"')"
    

    Você poderia fazer:

    sed "s/$TAB*\$/$CR/"
    

    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 sedem 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 unix2dosutilitário que não teria o problema:

    sed $'s/\t*$//' | unix2dos
    

    Ou use o modo perl's sed:

    perl -pe 's/\t*$//; s/\n/\r\n/'
    

    perl -pfunciona assim sedno sentido de rodar o código para cada linha de entrada, exceto que no perlespaç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ão sedoferece suporte apenas \ne apenas em expressões regulares) e pode lidar com arquivos que não sejam de texto.

    • 15
  3. jubilatious1
    2023-04-17T19:13:53+08:002023-04-17T19:13:53+08:00

    Usando Raku (anteriormente conhecido como Perl_6)

    ~$ cat unix2dos.raku
    my $fh1 = open $*IN, :r;
    #below :x opens write-only :exclusive (i.e. 'no-clobber')
    my $fh2 = open $*OUT, :x, nl-out => "\r\n";
    
    for $fh1.lines() { $fh2.put($_) };
    
    $fh1.close;
    $fh2.close;
    

    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-inparâmetro para entrada do identificador de arquivo (o padrão é ["\x0A", "\r\n"]), autochomps linhas por padrão, usa \nnovas linhas terminadas internamente e fornece um nl-outparâmetro para saída do identificador de arquivo (padrão é "\n").

    A declaração principal do OP é a seguinte:

    ... mas converteu o CR-LFpara LFo qual causou a falha do comando bcp.

    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ê linespreguiç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:

    ~$ raku unix2dos.raku < ends_with_LF.txt > ends_with_CRLF.txt
    

    O padrão do script acima é usar $*INstdin e, portanto, é "único", mas o Raku também fornece funções para leitura $*ARGFILESe diretórios. dirPor 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

    • 0

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve