faz linha para coluna n insere nova linha em todas as últimas linhas

0

eu tenho file.txt

john,
5901,
open

lina,
2401,
open

jody,
5401,
open

Eu quero inserir uma nova linha na última linha. O resultado deve ser:

john,5901,open
lina,2401,open
jody,5401,open

o que eu tento

cat file.txt | tr -d '\n'

mas o resultado é assim

john,5901,openlina,2401,openjody,5401,open
    
por Anggoro Setiawan 30.07.2018 / 11:50

4 respostas

2

Usando o Awk no modo de parágrafo :

$ awk -vRS= -vOFS= '{$1=$1} 1' file.txt
john,5901,open
lina,2401,open
jody,5401,open

Desativar o separador de registro com RS= faz com que o awk trate tudo entre as linhas vazias como um único registro e adiciona a nova linha à lista padrão de delimitadores de campo de entrada de espaço em branco. Como sua entrada não contém outro espaço em branco, isso significa que cada linha de um bloco se torna um campo. Em seguida, forçamos o registro a ser reavaliado, reatribuindo um valor de campo a si mesmo $1=$1 e, finalmente, imprimindo o registro com um separador de campo de saída vazio OFS= no lugar do espaço único padrão.

    
por 30.07.2018 / 13:23
1
$ paste -d '
$ sed -n 'H; /^$/{x;s/\n//g;p;d;}; ${x;s/\n//g;p;}' file
john,5901,open
lina,2401,open
jody,5401,open
' - - - - <file john,5901,open lina,2401,open jody,5401,open

Isso reformata os dados em quatro colunas, colocando cada linha do arquivo de entrada na próxima coluna. A linha vazia entre as seções é a quarta coluna e seria colocada por último em cada linha de saída, mas como está vazia, não conterá nada.

Os dados já têm vírgulas, por isso usamos um delimitador vazio com paste (com -d 'sed' ).

Uma solução usando H que não pressupõe que os dados sejam divididos em grupos de três linhas:

$ paste -d '
$ sed -n 'H; /^$/{x;s/\n//g;p;d;}; ${x;s/\n//g;p;}' file
john,5901,open
lina,2401,open
jody,5401,open
' - - - - <file john,5901,open lina,2401,open jody,5401,open

Isso é feito adicionando linhas ao espaço de espera com H e quando ele atinge uma linha vazia ou o final do arquivo, ele remove as novas linhas incorporadas no espaço de armazenamento que %code% adicionou e imprime o resultado .

    
por 30.07.2018 / 11:55
1

com awk

awk '{ printf (NF)?$0:RS } END{ print ""}' infile

Isso une todas as linhas em uma, se não for uma linha vazia (uma linha contendo um / conjunto de Tab, Space e Newline).

esta solução não depende das 3 linhas fixas em cada grupo.

para um caso específico, se você tivesse várias linhas vazias e, para evitar repetir aquelas em resultado, você pode fazer:

awk 'NF{ skip=0; printf $0; next} !skip{ printf RS; skip=1 } END{ print ""}' infile
    
por 30.07.2018 / 11:56
1

Uma maneira com o POSIXly sed pode ser:

sed -e '
    /./!d
    $ba
    N
    /\n$/!{H;s/.*//;x;D;}
    :a;s/\n//g
' input.txt

Entrada:

% cat -ne input.txt
 1  $
 2  $
 3  john,$
 4  5901,$
 5  open$
 6  $
 7  $
 8  $
 9  lina,$
10  2401,$
11  open$
12  $
13  jody,$
14  5401,$
15  open$

Saída:

john,5901,open
lina,2401,open
jody,5401,open

Explicação:

  • Sempre que sed vir uma linha não vazia (apenas qualquer caractere, até mesmo um espaço em branco serviria), ela será anexada ao espaço padrão e a próxima linha.
  • Agora, se a parte mais à direita do espaço do padrão, ou seja, a linha atual lida no espaço do padrão for uma linha vazia ou última linha, então vamos ao rótulo :a em que excluímos prontamente as novas linhas do espaço padrão imprimir para stdout.
  • E no caso de a linha de leitura justa não ser absoluta, após ser anexada ao espaço padrão, /\n$/ , voltamos e acrescentamos a próxima linha. Isso é feito por meio do comando D , que transfere o controle para o topo do código sed . Mas antes disso, ele limpa tudo até a primeira nova linha no espaço padrão. isso gerenciamos colocando um artefato \n by H;s/.*//;x .
por 30.07.2018 / 13:19