cole e salve o resultado no primeiro argumento sem usar arquivos temporários

3

Eu gostaria de usar paste para adicionar nova coluna no arquivo original "first.xls". Meus arquivos:

first.xls

1
1
1

second.xls

2
2
2

Estou usando:

paste -d'\t' first.xls  second.xls >> first.xls

e eu recebo first.xls :

1
1
1

1 2
1 2
1 2

mas o que eu quero é first.xls :

1 2
1 2
1 2

Eu não quero salvá-lo no novo arquivo. Eu quero sobrescrever first.xls do começo. Eu preciso disso porque eu quero colar nova coluna para meus últimos resultados para adicionar nova coluna com toda vez que eu executar o script

1 2 2
1 2 2
1 2 2

então

1 2 2 2
1 2 2 2
1 2 2 2

e assim por diante ...

    
por Paulius 08.11.2016 / 10:53

4 respostas

2

Usando esponja do pacote moreutils :

paste -d'\t' first.xls  second.xls | sponge first.xls

man sponge

sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file. This allows constricting pipelines that read from and write to the same file.

    
por 08.11.2016 / 15:18
0

Eu não acho que você pode fazer isso com paste sozinho.

Veja como eu faria:

paste -d' ' first.txt second.txt > tmpout && mv tmpout first.txt

Resultado após a primeira execução:

cat first.txt                   
1 2
1 2
1 2

Após a segunda execução:

cat first.txt 
1 2 2
1 2 2
1 2 2

... e terceira execução:

cat first.txt 
1 2 2 2
1 2 2 2
1 2 2 2
    
por 08.11.2016 / 11:08
0

Solução alternativa com awk

$ seq 3 > first.xls
$ seq 4 6 > second.xls

$ awk -v OFS="\t" 'NR==FNR{a[NR]=$0; next} {print a[FNR], $0 > "first.xls"}' first.xls second.xls 
$ cat first.xls 
1   4
2   5
3   6

$ awk -v OFS="\t" 'NR==FNR{a[NR]=$0; next} {print a[FNR], $0 > "first.xls"}' first.xls second.xls 
$ cat first.xls 
1   4   4
2   5   5
3   6   6
    
por 08.11.2016 / 12:05
0
A esponja

sugerida em outra resposta é a ferramenta certa para o trabalho!

sudo yum install moreutils
paste first.xls second.xls | sponge first.xls 

Este comando bash usando tee funciona para arquivos pequenos (< 2048 linhas):

CUIDADO: esse hack não funciona para arquivos maiores.

paste first.xls second.xls | tee first.xls >/dev/null

first.x second. result
1       2       1       2
1       2       1       2
1       2       1       2

Este comando executa a colagem em dois arquivos e depois canaliza para 'tee'. O comando tee RE-ABRE o arquivo (e stdout) para write . Então funciona. . mas é um pouco um hack. . funcionará em todos os sistemas? isso também funciona para arquivos grandes?

Veja aqui não exatamente a mesma pergunta, mas relevante: link

Seu problema é que seu comando abre primeiro.xls para escrever (anexar) e ler simultaneamente. Os dados são lidos do arquivo (depois combinados com colar com outro arquivo). Os dados de saída são então gravados (anexados) no arquivo. Os dados recém-gravados são lidos de volta, resultando no acréscimo - como seria de se esperar. Seu comando de acréscimo:

paste first.xls second.xls >> first.xls

first.x second. result
1       2       1
1       2       1
1       2       1
                1       2
                1       2
                1       2

Alterar o redirecionamento para abrir para sobrescrever também não funciona. Isso resulta no primeiro.xls sendo aberto e apagado antes de ser lido. E você recebe uma coluna em branco + 2 colunas. Substituir em vez de anexar não funciona de maneira diferente:

paste first.xls second.xls > first.xls

first.x second. result
1       2               2
1       2               2
1       2               2

TESTANDO arquivos maiores

1000 linhas que funcionam:

yes "1" | fmt -2 |head -1000 >1000.1
yes "2" | fmt -2 |head -1000 >1000.2
paste 1000.1 1000.2 |tee 1000.1 >/dev/null
uniq -c 1000.1 
 1000 1 2

10000 linhas começamos a ver um problema semelhante novamente :

Interessante vermos depois de 2048 linhas :-) A adivinhação é causada pelo limite do buffer de disco ou talvez pelo limite do buffer de tubo. . .

yes "1" | fmt -2 |head -10000 >10000.1
yes "2" | fmt -2 |head -10000 >10000.2
paste 10000.1 10000.2 |tee 10000.1 >/dev/null
uniq -c 10000.1 
 2048 1 2
 7952   2
    
por 08.11.2016 / 14:37