Tentando adicionar uma nova linha ao comando colar

Tentando adicionar uma nova linha ao comando colar

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 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 errado ao usar uma nova linha no comando colar?

Aqui está meu produto final: 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

Responder1

Tente esta solução com dois arquivos temporários extras:

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

Esta solução foi baseada no pressuposto de que a -dopção seleciona o delimitadorglobalmentepara todos os arquivos de entrada, então fique em brancoouuma nova linha. De certa forma, isso é verdade, pois as ocorrências posteriores -dsobrescrevem as anteriores. Porém, como apontou @DigitalTrauma, podemos fornecer mais de um delimitador que será usado sequencialmente. Portanto, a solução do @DigitalTrauma é mais elegante que a minha, pois evita completamente arquivos temporários adicionais.

Uma aplicação de nicho para minha solução seria o caso em que um ou mais delimitadores commais de um personagem cadatem que ser usado. Isso não deveria ser possível apenas usando a -dopção.

Responder2

Acho que esta parte da pastepágina de manual é o que você deseja:

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

Portanto, esta linha deve funcionar para o seu caso:

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

Funciona conforme 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 pasteGNU Coreutils 5.97 e 8.21 e BSD (OS X). Não tenho certeza de quais outras versões de paste existem por aí.

Responder3

Este comando deve funcionar.

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

Responder4

sort -dk2,2 phpbook |
sed "s/\t/\n/3;s//\n/2;s// /g"

Pelo que entendi, você tem um arquivo chamado phpbookque consiste em linhas de entradas da lista telefônica semelhantes a esta:

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

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

Você deve observar que sortdelimita por <TAB>caracteres por padrão:

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

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

Pensando nisso é mais um pouco e suponho que seja bem provável que seus delimitadores estejam misturados e o sedobjetivo inicial seja normalizá-los. Isso faz sentido. Talvez tipo:

1,2\t3\t4,5,6

...ou alguma coisa. Nesse caso é necessária uma tradução inicial de algum tipo. Então talvez...

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

funcionaria um pouco melhor. Também...

sort ... -k 2

...poderser problemático em casos extremos porque quando você o usa, você sortnãoapenaso segundo campo, mas sim do segundo campo até o final da linha. Em geral, quando as pessoas fazem isso, elas realmente querem -k2,2o que os dados sortconsideramapenaso segundo campo.

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

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

...qual seriasort principalmenteem sobrenomes esecundariamentenos primeiros nomes. Dessa formaZed SmithseguiriaAlfa Smithtoda vez.

De qualquer forma, caso eu esteja certo, o sort | sedpipeline acima deve fazer tudo. Presumo que você sedentenda os \ecenários que usei, mas se não, você pode tentar substituir o sedscript citado por:

s/<literal TAB>/\
/3;s//\
/2;s// /g

informação relacionada