Tentando adicionar uma nova linha ao comando paste

5

Aqui está a tentativa fraca de um comando colar tentando incluir uma nova linha:

    paste -d -s tmp1 tmp2 \n tmp3 \n tmp4 tmp5 tmp6 > tmp7

Basicamente eu tenho várias linhas em cada tmp e quero que a saída seja lida

First(tmp1) Last(tmp2)
Address(tmp3)
City(tmp4) State(tmp5) Zip(tmp6)

Estou fora da base de usar uma nova linha no comando paste?

Aqui está o meu produto acabado: OBRIGADO PELA AJUDA!

    cp phbook phbookh2p5

    sed 's/\t/,/g' phbookh2p5 > tmp
    sort -k2 -t ',' -d tmp > tmp0
    cut -d',' -f1,2 tmp0 > tmp1
    cut -d',' -f3 tmp0 > tmp2
    cut -d',' -f4,5,6 tmp0 > tmp3
    echo "" > tmp4

    paste -d '\n' tmp1 tmp2 tmp3 tmp4 > tmp7

    sed 's/\t/ /g' tmp7 > phbookh2p5

    cat phbookh2p5

    rm tmp*; rm phbookh2p5
    
por user3347022 15.10.2014 / 23:10

5 respostas

7

Experimente esta solução com dois arquivos temporários adicionais:

paste tmp1 tmp2 > tmp12
paste tmp4 tmp5 tmp6 > tmp456
paste -d "\n" tmp12 tmp3 tmp456 > tmp7

Esta solução foi baseada na suposição de que a opção -d seleciona o delimitador globalmente para todos os arquivos de entrada, de modo que seja uma ou uma nova linha em branco. De certo modo isso é verdade, pois ocorrências posteriores de -d sobrescrevem as anteriores. No entanto, como apontado @DigitalTrauma, podemos fornecer mais de um delimitador que será usado sequencialmente. Então, a solução da @ DigitalTrauma é mais elegante que a minha, já que evita completamente arquivos temporários adicionais.

Um aplicativo de nicho para minha solução seria o caso em que um ou delimitadores com mais de um caractere cada precisam ser usados. Isso não deve ser possível usando apenas a opção -d .

    
por 15.10.2014 / 23:24
4

Acho que esta parte da página paste man é o que você quer:

   -d, --delimiters=LIST
          reuse characters from LIST instead of TABs

Portanto, este one-liner deve funcionar para o seu caso:

paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 > tmp7

Funciona como esperado com os dados de amostra do @DopeGhoti:

$ grep . tmp*
tmp1:Bill
tmp1:Bob
tmp2:Kerman
tmp2:Germin
tmp3:123 Main St.
tmp3:321 Sesame St.
tmp4:Kerbopalis
tmp4:Kerbington
tmp5:Kerbskatchewan
tmp5:Kermont
tmp6:12345
tmp6:31416
$ paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6
Bill Kerman
123 Main St.
Kerbopalis Kerbskatchewan 12345
Bob Germin
321 Sesame St.
Kerbington Kermont 31416
$ 

Eu testei isso com sucesso com paste do GNU Coreutils 5.97 e 8.21 e BSD (OS X). Não tenho certeza de quais outras versões da pasta estão disponíveis.

    
por 16.10.2014 / 01:51
1

Este comando deve funcionar.

 paste -s tmp1 tmp2 -d '\n' tmp3 -d '\n' tmp4 tmp5 tmp6 > tmp7
    
por 15.10.2014 / 23:18
0

Você pode conseguir combinando paste e awk :

paste -d'|' tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 | awk 'BEGIN { FS = "|" }; {print $1, $2 "\n" $3 "\n" $4, $5, $6}' > tmp7

Exemplo de saída de alguns dados de teste que eu usei para os arquivos tmp:

Bill Kerman
123 Main St.
Kerbopalis Kerbskatchewan 12345
Bob Germin
321 Sesame St.
Kerbington Kermont 31416
    
por 15.10.2014 / 23:24
-1
sort -dk2,2 phpbook |
sed "s/\t/\n/3;s//\n/2;s// /g"

Pelo que entendi, você tem um arquivo chamado phpbook que consiste em linhas de entradas de catálogo telefônico que se parecem com isso:

{first}\t{last}\t{address}\t{city}\t{state}\t{zip}

Você deseja classificá-las em {last} , adicionar novas linhas seguindo {last} e {address} para cada entrada, traduzir \t abs para <spaces> e depois imprimir os resultados em stdout . Se não for esse o caso, não sei o que mais o seu comando faria - mas às vezes posso ser bastante denso.

Você deve observar que sort delimita por <TAB> caracteres por padrão, portanto:

sed 's/\t/,/g' | sort ... -t ,

... provavelmente não vale a pena fazer.

Pensar é um pouco mais e suponho que seja muito provável que os seus delimitadores sejam mistos e que o sed inicial pretenda normalizá-los. Isso faz sentido. Talvez como:

1,2\t3\t4,5,6

... ou algo assim. Nesse caso, uma tradução inicial de algum tipo é necessária. Então talvez ...

tr , \t <phbook | sort ... | sed ...

trabalharia um pequeno bettet. Também ...

sort ... -k 2

... pode ser problemático em casos de borda porque quando você o usa, você não sort em somente o segundo campo, mas sim do segundo campo para o fim da linha. Em geral, quando as pessoas fazem isso, elas realmente querem -k2,2 , que confina os dados sort considera somente o segundo campo.

Também pode valer a pena adicionar uma chave secundária como:

...sort -dk2,2 -k1,1

... qual seria sort principalmente em sobrenomes e secundariamente em nomes próprios. Dessa forma, Zed Smith seguiria Alpha Smith todas as vezes.

De qualquer forma, se eu estiver certo, o sort | sed pipeline acima deve fazer a coisa toda. Estou assumindo que seu sed entende os \e scapes que usei, mas se isso não acontecer, você pode tentar substituir o script sed entre aspas por:

s/<literal TAB>/\
/3;s//\
/2;s// /g
    
por 16.10.2014 / 12:33