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 / 708318
Accepted
SeetheMoar
SeetheMoar
Asked: 2022-07-02 15:04:36 +0800 CST2022-07-02 15:04:36 +0800 CST 2022-07-02 15:04:36 +0800 CST

Como dividir uma única linha de campos delimitados por vírgulas em várias linhas com um número específico de campos em cada linha?

  • 772

eu tenho um arquivo assim

Hello,Hi,Hullo,Hammers,Based,Random

Para n=2, a saída deve ser assim

Hello,Hi
Hullo,Hammers
Based,Random

Para n=3, a saída deve ser assim

Hello,Hi,Hullo
Hammers,Based,Random

Como eu poderia fazer isso usando awk/sed?

Editar: né um fator de número de campos

awk text-processing
  • 9 9 respostas
  • 215 Views

9 respostas

  • Voted
  1. Best Answer
    Ed Morton
    2022-07-02T19:37:50+08:002022-07-02T19:37:50+08:00
    $ awk -v n=2 -F',' '{for (i=1;i<=NF;i++) printf "%s%s", $i, (i%n ? FS : ORS)}' file
    Hello,Hi
    Hullo,Hammers
    Based,Random
    
    $ awk -v n=3 -F',' '{for (i=1;i<=NF;i++) printf "%s%s", $i, (i%n ? FS : ORS)}' file
    Hello,Hi,Hullo
    Hammers,Based,Random
    

    Na sua pergunta, você não abordou como lidar com casos em que o número de campos não se divide igualmente, nentão também não abordei aqui.

    • 4
  2. r_31415
    2022-07-03T09:08:30+08:002022-07-03T09:08:30+08:00

    Outra abordagem com tre paste:

    Para n=2,

    $ <input tr ',' '\n' | paste  -d ',' - -
    Hello,Hi
    Hullo,Hammers
    Based,Random
    

    Para n=3,

    $ <input tr ',' '\n' | paste  -d ',' - - -
    Hello,Hi,Hullo
    Hammers,Based,Random
    
    • 3
  3. cas
    2022-07-02T19:05:10+08:002022-07-02T19:05:10+08:00

    Usando perl:

    $ echo 'Hello,Hi,Hullo,Hammers,Based,Random' | 
        perl -F, -le '
          BEGIN { $n = shift };
          for ($i=0; $i < @F; $i += $n) {
             print join(",", @F[$i .. ($i + $n - 1)]);
          }' 2
    Hello,Hi
    Hullo,Hammers
    Based,Random
    

    Isso usa o primeiro argumento como o número de entradas impressas por linha de saída (usando variável $n). STDIN e quaisquer argumentos de nome de arquivo são usados ​​como entrada.

    Devido à -F,opção (que habilita implicitamente as opções -ae -n), ele lê automaticamente cada linha de entrada e a divide em vírgulas em array @F, então itera sobre os índices do array, $nitens por vez. $nelementos são impressos em cada linha de saída.

    OBSERVAÇÃO: use o módulo Text::CSV se precisar analisar o CSV real com campos entre aspas e vírgulas incorporados em aspas em vez de uma entrada simples delimitada por vírgulas.

    Saída com um argumento de 3em vez de 2:

    $ echo 'Hello,Hi,Hullo,Hammers,Based,Random' | perl -F, -le 'BEGIN{$n = shift};for($i=0;$i<@F;$i+=$n){print join(",",@F[$i..($i+$n-1)])}' 3
    Hello,Hi,Hullo
    Hammers,Based,Random
    

    E novamente com 4:

    $ echo 'Hello,Hi,Hullo,Hammers,Based,Random' | perl -F, -le 'BEGIN{$n = shift};for($i=0;$i<@F;$i+=$n){print join(",",@F[$i..($i+$n-1)])}' 4
    Hello,Hi,Hullo,Hammers
    Based,Random,,
    
    • 2
  4. guest_7
    2022-07-02T20:04:32+08:002022-07-02T20:04:32+08:00
    sed 's/,/\n/2;P;D' 
    
    m=3
    sed "s/,/\\n/$m;P;D"
    
    • 2
  5. Thibault LE PAUL
    2022-07-03T23:52:13+08:002022-07-03T23:52:13+08:00

    awknovamente,
    insira qualquer conjunto de valores separados por ,e novas linhas, produza
    um csv de largura fixa:

    awk '{printf((FNR>1?(FNR-1)%n?",":ORS:"")$0)}END{print ""}' RS='[,\n]' n=4 <<END
    Hello
    Hi,Hullo,Hammers,Based
    Random
    END
    
    Hello,Hi,Hullo,Hammers
    Based,Random
    
    • 2
  6. DanieleGrassini
    2022-07-03T23:23:59+08:002022-07-03T23:23:59+08:00

    Com perl:

    echo 'Hello,Hi,Hullo,Hammers,Based,Random' | perl -ne '
        @L = (/,?([^,]*,[^,]*)/g);
        $"="\n" ; print "@L"
    '
    

    Esta pergunta me faz pensar em python zip/iter funções internas :

    python3 -c 'from sys import argv as F; J = "\n".join
    _, sep, data, sz = F
    L = [*map(sep.join, zip(*[iter(data.split(sep))]*int(sz)))]
    print(J(L))
    ' , "Hello,Hi,Hullo,Hammers,Based,Random" 2
    
    • 1
  7. jubilatious1
    2022-07-05T20:30:07+08:002022-07-05T20:30:07+08:00

    Usando Raku (anteriormente conhecido como Perl_6)

    ~$ raku -ne '.put for .split(",").rotor(3);'  file
    

    Entrada de amostra:

    Hello,Hi,Hullo,Hammers,Based,Random
    

    Saída de amostra com .rotor(3)(de cima):

    Hello Hi Hullo
    Hammers Based Random
    

    Saída de amostra mudando acima para .rotor(2):

    Hello Hi
    Hullo Hammers
    Based Random
    

    O código acima é uma implementação básica no Raku (retornando um único espaço em branco entre as colunas). A rotor()chamada determina o número de colunas [ veja a discussão abaixo sobre a diferença entre rotor()e batch()]. Basta adicionar uma chamada para .join()se quiser juntar colunas usando vírgulas, tabulações, barras verticais, etc.:

    ~$ raku -ne '.join(",").put for .split(",").rotor(2);'  file
    Hello,Hi
    Hullo,Hammers
    Based,Random
    

    Observe que, por padrão, rotor()retorna apenas grupos completos e descartará grupos parciais no final. Portanto, realizar uma rotor(4)chamada na amostra de seis elementos acima resultará em uma única linha de saída, com 4 elementos. Para garantir que não haja perda de dados, use rotor(4, :partial)ou batch(4).

    ~$ raku -ne '.join(",").put for .split(",").rotor(4);'  file
    Hello,Hi,Hullo,Hammers
    
    #COMPARE TO:
    
    ~$ raku -ne '.join(",").put for .split(",").batch(4);'  file
    Hello,Hi,Hullo,Hammers
    Based,Random
    

    O processamento por um analisador CSV autêntico (por exemplo, o Text::CSVmódulo Raku) validará o arquivo CSV resultante. Consulte o URL abaixo para obter exemplos.

    https://unix.stackexchange.com/a/701805/227738
    https://raku.org

    • 1
  8. HatLess
    2022-07-02T15:41:44+08:002022-07-02T15:41:44+08:00

    Usandosed

    $ sed -E 's/([^,]*,[^,]*),/\1\
    /g' input_file
    Hello,Hi
    Hullo,Hammers
    Based,Random
    
    $ sed -E 's/(([^,]*,){2}[^,]*),/\1\
    /g' input_file
    Hello,Hi,Hullo
    Hammers,Based,Random
    
    • 0
  9. jmk
    2022-07-02T23:26:27+08:002022-07-02T23:26:27+08:00

    Além da abordagem óbvia awk/Perl/sed, posso recomendar Miller

    Ele pode extrair e modificar dados baseados em texto muito bem e é mais intuitivo de usar do que suas contrapartes.

    • -1

relate perguntas

  • Reorganize as letras e compare duas palavras

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Embaralhamento de arquivo de várias linhas

  • como posso alterar o caso do caractere (de baixo para cima e vice-versa)? ao mesmo tempo [duplicado]

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