Classificação única: Redirecionar saída para o mesmo arquivo

12

Existe alguma maneira de salvar a saída do pipe no mesmo arquivo que é processado. Por exemplo, é isso que estou fazendo de verdade

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

Eu queria saber se havia uma maneira de fazer isso em apenas uma linha (não anexar esses comandos usando & amp; & amp;)

Este não é o caminho, mas para ter uma ideia

$ cat filename | sort | uniq > filename
    
por whitenoisedb 26.09.2014 / 07:26

5 respostas

15

Você pode usar sponge do pacote moreutils :

LC_ALL=C sort -u filename | sponge filename

Você também não precisa canalizar para uniq , desde quando a opção sort tem -u para linhas exclusivas ao classificar.

Note que no sistema GNU com localidades UTF-8, sort -u ou sort | uniq não fornecem linhas exclusivas, mas o primeiro da sequência de linhas que ordenam o mesmo na localidade atual.

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq
①

forneceu apenas . Alterar o código de idioma para C forçará a ordem de classificação com base nos valores de bytes:

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq
①
②
    
por cuonglm 26.09.2014 / 07:48
11

Você não precisa de nenhum comando extra como cat e uniq e também sem usar o comando rm e mv para remover e renomear o nome do arquivo. basta usar um comando simples.

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

Como funciona?

O comando

sort classifica seu nome de arquivo e, com a opção -u , remove linhas duplicadas dele. então, com a opção -o , grava a saída no mesmo arquivo com o método no lugar.

    
por αғsнιη 26.09.2014 / 08:10
3

Seu exemplo sugerido (abaixo) não funciona porque você realmente lê e escreve no mesmo arquivo simultaneamente.

$ cat filename | sort | uniq > filename

A ideia com um canal ou redirecionamento é que o comando no lado esquerdo e direito de cada canal ou redirecionamento seja executado simultaneamente, em paralelo. O comando à direita processa as informações conforme elas são entregues a ela a partir do comando à esquerda, enquanto o comando à esquerda ainda está em execução.

Para que seu cenário funcione, o comando que lê a partir do arquivo deve ser concluído antes que o comando que grava no arquivo seja iniciado. Para que isso funcione, você precisará redirecionar a saída para um local temporário primeiro e, depois de concluído, enviá-lo do local temporário de volta para o arquivo.

A melhor maneira de fazer isso é basicamente como no seu exemplo anterior, onde você redireciona para um arquivo temporário e renomeia esse arquivo para o original (exceto que você não precisa excluir o arquivo primeiro, porque mover exclui qualquer arquivo alvo existente).

$ cat filename | sort | uniq > result
$ mv -f result filename

Você também pode salvá-lo em uma variável de string, exceto que isso só funciona quando os dados são pequenos o suficiente para caber na memória de uma só vez.

    
por thomasrutter 26.09.2014 / 07:50
1

Você pode usar o comando tee :

sort -u filename | tee filename > /dev/null

O comando tee lê a entrada padrão e grava nos arquivos de saída padrão e .

    
por Sylvain Pineau 26.09.2014 / 09:11
0

Você pode usar o Vim no modo Ex:

ex -sc 'sort u|x' filename
  1. sort u sort unique

  2. x escreve se foram feitas alterações (elas foram) e sai

por Steven Penny 11.04.2016 / 00:55